示例#1
0
MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
  const double lightness,Quantum *red,Quantum *green,Quantum *blue)
{
  MagickRealType
    b,
    g,
    r,
    m1,
    m2;

  /*
    Convert HSL to RGB colorspace.
  */
  assert(red != (Quantum *) NULL);
  assert(green != (Quantum *) NULL);
  assert(blue != (Quantum *) NULL);
  if (saturation == 0)
    {
      *red=ClampToQuantum((MagickRealType) QuantumRange*lightness);
      *green=(*red);
      *blue=(*red);
      return;
    }
  if (lightness < 0.5)
    m2=lightness*(saturation+1.0);
  else
    m2=(lightness+saturation)-(lightness*saturation);
  m1=2.0*lightness-m2;
  r=ConvertHueToRGB(m1,m2,hue+1.0/3.0);
  g=ConvertHueToRGB(m1,m2,hue);
  b=ConvertHueToRGB(m1,m2,hue-1.0/3.0);
  *red=ClampToQuantum((MagickRealType) QuantumRange*r);
  *green=ClampToQuantum((MagickRealType) QuantumRange*g);
  *blue=ClampToQuantum((MagickRealType) QuantumRange*b);
}
示例#2
0
文件: _api.c 项目: harvimt/sanpera
void sanpera_magick_pixel_from_doubles(MagickPixelPacket *pixel, double in[4]) {
    SetPixelRed(pixel, ClampToQuantum(in[0] * QuantumRange));
    SetPixelGreen(pixel, ClampToQuantum(in[1] * QuantumRange));
    SetPixelBlue(pixel, ClampToQuantum(in[2] * QuantumRange));
    // Distinct from "opacity", which treats 0 as opaque
    SetPixelAlpha(pixel, ClampToQuantum(in[3] * QuantumRange));
}
示例#3
0
文件: _api.c 项目: harvimt/sanpera
void sanpera_magick_pixel_from_doubles_channel(
        MagickPixelPacket *pixel, double in[4], ChannelType channels)
{
    if (channels & RedChannel)
        SetPixelRed(pixel, ClampToQuantum(in[0] * QuantumRange));
    if (channels & GreenChannel)
        SetPixelGreen(pixel, ClampToQuantum(in[1] * QuantumRange));
    if (channels & BlueChannel)
        SetPixelBlue(pixel, ClampToQuantum(in[2] * QuantumRange));
    // Distinct from "opacity", which treats 0 as opaque
    if (channels & AlphaChannel)
        SetPixelAlpha(pixel, ClampToQuantum(in[3] * QuantumRange));
}
示例#4
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   G e t O n e C a c h e V i e w V i r t u a l P i x e l                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  GetOneCacheViewVirtualPixel() returns a single pixel at the specified (x,y)
%  location.  The image background color is returned if an error occurs.  If
%  you plan to modify the pixel, use GetOneCacheViewAuthenticPixel() instead.
%
%  The format of the GetOneCacheViewVirtualPixel method is:
%
%      MagickBooleanType GetOneCacheViewVirtualPixel(
%        const CacheView *cache_view,const ssize_t x,const ssize_t y,
%        Quantum *pixel,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o cache_view: the cache view.
%
%    o x,y:  These values define the offset of the pixel.
%
%    o pixel: return a pixel at the specified (x,y) location.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType GetOneCacheViewVirtualPixel(
  const CacheView *cache_view,const ssize_t x,const ssize_t y,Quantum *pixel,
  ExceptionInfo *exception)
{
  const int
    id = GetOpenMPThreadId();

  register const Quantum
    *magick_restrict p;

  register ssize_t
    i;

  assert(cache_view != (CacheView *) NULL);
  assert(cache_view->signature == MagickCoreSignature);
  assert(id < (int) cache_view->number_threads);
  (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
  p=GetVirtualPixelsFromNexus(cache_view->image,
    cache_view->virtual_pixel_method,x,y,1,1,cache_view->nexus_info[id],
    exception);
  if (p == (const Quantum *) NULL)
    {
      PixelInfo
        background_color;

      background_color=cache_view->image->background_color;
      pixel[RedPixelChannel]=ClampToQuantum(background_color.red);
      pixel[GreenPixelChannel]=ClampToQuantum(background_color.green);
      pixel[BluePixelChannel]=ClampToQuantum(background_color.blue);
      pixel[BlackPixelChannel]=ClampToQuantum(background_color.black);
      pixel[AlphaPixelChannel]=ClampToQuantum(background_color.alpha);
      return(MagickFalse);
    }
  for (i=0; i < (ssize_t) GetPixelChannels(cache_view->image); i++)
  {
    PixelChannel channel=GetPixelChannelChannel(cache_view->image,i);
    pixel[channel]=p[i];
  }
  return(MagickTrue);
}
示例#5
0
static int PrintChannelStatistics(FILE *file,const ChannelType channel,
                                  const char *name,const double scale,
                                  const ChannelStatistics *channel_statistics)
{
#define StatisticsFormat "    %s:\n      min: " QuantumFormat  \
  " (%g)\n      max: " QuantumFormat " (%g)\n"  \
  "      mean: %g (%g)\n      standard deviation: %g (%g)\n"  \
  "      kurtosis: %g\n      skewness: %g\n"

    int
    status;

    if (channel == AlphaChannel)
    {
        status=fprintf(file,StatisticsFormat,name,ClampToQuantum(scale*
                       (QuantumRange-channel_statistics[channel].maxima)),
                       (QuantumRange-channel_statistics[channel].maxima)/(double) QuantumRange,
                       ClampToQuantum(scale*(QuantumRange-channel_statistics[channel].minima)),
                       (QuantumRange-channel_statistics[channel].minima)/(double) QuantumRange,
                       scale*(QuantumRange-channel_statistics[channel].mean),(QuantumRange-
                               channel_statistics[channel].mean)/(double) QuantumRange,scale*
                       channel_statistics[channel].standard_deviation,
                       channel_statistics[channel].standard_deviation/(double) QuantumRange,
                       channel_statistics[channel].kurtosis,
                       channel_statistics[channel].skewness);
        return(status);
    }
    status=fprintf(file,StatisticsFormat,name,ClampToQuantum(scale*
                   channel_statistics[channel].minima),channel_statistics[channel].minima/
                   (double) QuantumRange,ClampToQuantum(scale*
                           channel_statistics[channel].maxima),channel_statistics[channel].maxima/
                   (double) QuantumRange,scale*channel_statistics[channel].mean,
                   channel_statistics[channel].mean/(double) QuantumRange,scale*
                   channel_statistics[channel].standard_deviation,
                   channel_statistics[channel].standard_deviation/(double) QuantumRange,
                   channel_statistics[channel].kurtosis,channel_statistics[channel].skewness);
    return(status);
}
示例#6
0
static ssize_t PrintChannelStatistics(FILE *file,const PixelChannel channel,
  const char *name,const double scale,
  const ChannelStatistics *channel_statistics)
{
#define StatisticsFormat "    %s:\n      min: " QuantumFormat  \
  " (%g)\n      max: " QuantumFormat " (%g)\n"  \
  "      mean: %g (%g)\n      standard deviation: %g (%g)\n"  \
  "      kurtosis: %g\n      skewness: %g\n"

  ssize_t
    n;

  n=FormatLocaleFile(file,StatisticsFormat,name,ClampToQuantum(scale*
    channel_statistics[channel].minima),channel_statistics[channel].minima/
    (double) QuantumRange,ClampToQuantum(scale*
    channel_statistics[channel].maxima),channel_statistics[channel].maxima/
    (double) QuantumRange,scale*channel_statistics[channel].mean,
    channel_statistics[channel].mean/(double) QuantumRange,scale*
    channel_statistics[channel].standard_deviation,
    channel_statistics[channel].standard_deviation/(double) QuantumRange,
    channel_statistics[channel].kurtosis,channel_statistics[channel].skewness);
  return(n);
}
示例#7
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   C o n v e r t H W B T o R G B                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ConvertHWBToRGB() transforms a (hue, whiteness, blackness) to a (red, green,
%  blue) triple.
%
%  The format of the ConvertHWBToRGBImage method is:
%
%      void ConvertHWBToRGB(const double hue,const double whiteness,
%        const double blackness,Quantum *red,Quantum *green,Quantum *blue)
%
%  A description of each parameter follows:
%
%    o hue, whiteness, blackness: A double value representing a
%      component of the HWB color space.
%
%    o red, green, blue: A pointer to a pixel component of type Quantum.
%
*/
MagickExport void ConvertHWBToRGB(const double hue,const double whiteness,
  const double blackness,Quantum *red,Quantum *green,Quantum *blue)
{
  MagickRealType
    b,
    f,
    g,
    n,
    r,
    v;

  register ssize_t
    i;

  /*
    Convert HWB to RGB colorspace.
  */
  assert(red != (Quantum *) NULL);
  assert(green != (Quantum *) NULL);
  assert(blue != (Quantum *) NULL);
  v=1.0-blackness;
  if (hue == 0.0)
    {
      *red=ClampToQuantum((MagickRealType) QuantumRange*v);
      *green=ClampToQuantum((MagickRealType) QuantumRange*v);
      *blue=ClampToQuantum((MagickRealType) QuantumRange*v);
      return;
    }
  i=(ssize_t) floor(6.0*hue);
  f=6.0*hue-i;
  if ((i & 0x01) != 0)
    f=1.0-f;
  n=whiteness+f*(v-whiteness);  /* linear interpolation */
  switch (i)
  {
    default:
    case 6:
    case 0: r=v; g=n; b=whiteness; break;
    case 1: r=n; g=v; b=whiteness; break;
    case 2: r=whiteness; g=v; b=n; break;
    case 3: r=whiteness; g=n; b=v; break;
    case 4: r=n; g=whiteness; b=v; break;
    case 5: r=v; g=whiteness; b=n; break;
  }
  *red=ClampToQuantum((MagickRealType) QuantumRange*r);
  *green=ClampToQuantum((MagickRealType) QuantumRange*g);
  *blue=ClampToQuantum((MagickRealType) QuantumRange*b);
}
示例#8
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d E X R I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadEXRImage reads an image in the high dynamic-range (HDR) file format
%  developed by Industrial Light & Magic.  It allocates the memory necessary
%  for the new Image structure and returns a pointer to the new image.
%
%  The format of the ReadEXRImage method is:
%
%      Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  const ImfHeader
    *hdr_info;

  Image
    *image;

  ImageInfo
    *read_info;

  ImfInputFile
    *file;

  ImfRgba
    *scanline;

  int
    max_x,
    max_y,
    min_x,
    min_y;

  MagickBooleanType
    status;

  register ssize_t
    x;

  register Quantum
    *q;

  ssize_t
    y;

  /*
    Open image.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AcquireImage(image_info,exception);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  read_info=CloneImageInfo(image_info);
  if (IsPathAccessible(read_info->filename) == MagickFalse)
    {
      (void) AcquireUniqueFilename(read_info->filename);
      (void) ImageToFile(image,read_info->filename,exception);
    }
  file=ImfOpenInputFile(read_info->filename);
  if (file == (ImfInputFile *) NULL)
    {
      ThrowFileException(exception,BlobError,"UnableToOpenBlob",
        ImfErrorMessage());
      read_info=DestroyImageInfo(read_info);
      return((Image *) NULL);
    }
  hdr_info=ImfInputHeader(file);
  ImfHeaderDataWindow(hdr_info,&min_x,&min_y,&max_x,&max_y);
  image->columns=max_x-min_x+1UL;
  image->rows=max_y-min_y+1UL;
  image->matte=MagickTrue;
  if (image_info->ping != MagickFalse)
    {
      (void) ImfCloseInputFile(file);
      if (LocaleCompare(image_info->filename,read_info->filename) != 0)
        (void) RelinquishUniqueFileResource(read_info->filename);
      read_info=DestroyImageInfo(read_info);
      (void) CloseBlob(image);
      return(GetFirstImageInList(image));
    }
  scanline=(ImfRgba *) AcquireQuantumMemory(image->columns,sizeof(*scanline));
  if (scanline == (ImfRgba *) NULL)
    {
      (void) ImfCloseInputFile(file);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    if (q == (Quantum *) NULL)
      break;
    ImfInputSetFrameBuffer(file,scanline-min_x-image->columns*(min_y+y),1,
      image->columns);
    ImfInputReadPixels(file,min_y+y,min_y+y);
    for (x=0; x < (ssize_t) image->columns; x++)
    {
      SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
        ImfHalfToFloat(scanline[x].r)),q);
      SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
        ImfHalfToFloat(scanline[x].g)),q);
      SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
        ImfHalfToFloat(scanline[x].b)),q);
      SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
        ImfHalfToFloat(scanline[x].a)),q);
      q+=GetPixelChannels(image);
    }
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
  }
  scanline=(ImfRgba *) RelinquishMagickMemory(scanline);
  (void) ImfCloseInputFile(file);
  if (LocaleCompare(image_info->filename,read_info->filename) != 0)
    (void) RelinquishUniqueFileResource(read_info->filename);
  read_info=DestroyImageInfo(read_info);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   C o n v e r t H C L T o R G B                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ConvertHCLToRGB() transforms a (hue, chroma, luma) to a (red, green,
%  blue) triple.
%
%  The format of the ConvertHCLToRGBImage method is:
%
%      void ConvertHCLToRGB(const double hue,const double chroma,
%        const double luma,Quantum *red,Quantum *green,Quantum *blue)
%
%  A description of each parameter follows:
%
%    o hue, chroma, luma: A double value representing a
%      component of the HCL color space.
%
%    o red, green, blue: A pointer to a pixel component of type Quantum.
%
*/
MagickExport void ConvertHCLToRGB(const double hue,const double chroma,
  const double luma,Quantum *red,Quantum *green,Quantum *blue)
{
  double
    b,
    c,
    g,
    h,
    m,
    r,
    x;

  /*
    Convert HCL to RGB colorspace.
  */
  assert(red != (Quantum *) NULL);
  assert(green != (Quantum *) NULL);
  assert(blue != (Quantum *) NULL);
  h=6.0*hue;
  c=chroma;
  x=c*(1.0-fabs(fmod(h,2.0)-1.0));
  r=0.0;
  g=0.0;
  b=0.0;
  if ((0.0 <= h) && (h < 1.0))
    {
      r=c;
      g=x;
    }
  else
    if ((1.0 <= h) && (h < 2.0))
      {
        r=x;
        g=c;
      }
    else
      if ((2.0 <= h) && (h < 3.0))
        {
          g=c;
          b=x;
        }
      else
        if ((3.0 <= h) && (h < 4.0))
          {
            g=x;
            b=c;
          }
        else
          if ((4.0 <= h) && (h < 5.0))
            {
              r=x;
              b=c;
            }
          else
            if ((5.0 <= h) && (h < 6.0))
              {
                r=c;
                b=x;
              }
  m=luma-(0.298839f*r+0.586811f*g+0.114350f*b);
  *red=ClampToQuantum(QuantumRange*(r+m));
  *green=ClampToQuantum(QuantumRange*(g+m));
  *blue=ClampToQuantum(QuantumRange*(b+m));
}
示例#10
0
static MagickBooleanType ForwardFourier(const FourierInfo *fourier_info,
  Image *image,double *magnitude,double *phase,ExceptionInfo *exception)
{
  CacheView
    *magnitude_view,
    *phase_view;

  double
    *magnitude_source,
    *phase_source;

  Image
    *magnitude_image,
    *phase_image;

  MagickBooleanType
    status;

  register IndexPacket
    *indexes;

  register ssize_t
    x;

  register PixelPacket
    *q;

  ssize_t
    i,
    y;

  magnitude_image=GetFirstImageInList(image);
  phase_image=GetNextImageInList(image);
  if (phase_image == (Image *) NULL)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
        "ImageSequenceRequired","`%s'",image->filename);
      return(MagickFalse);
    }
  /*
    Create "Fourier Transform" image from constituent arrays.
  */
  magnitude_source=(double *) AcquireQuantumMemory((size_t)
    fourier_info->height,fourier_info->width*sizeof(*magnitude_source));
  if (magnitude_source == (double *) NULL)
    return(MagickFalse);
  (void) ResetMagickMemory(magnitude_source,0,fourier_info->height*
    fourier_info->width*sizeof(*magnitude_source));
  phase_source=(double *) AcquireQuantumMemory((size_t) fourier_info->height,
    fourier_info->width*sizeof(*phase_source));
  if (phase_source == (double *) NULL)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),
        ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
      magnitude_source=(double *) RelinquishMagickMemory(magnitude_source);
      return(MagickFalse);
    }
  status=ForwardQuadrantSwap(fourier_info->height,fourier_info->height,
    magnitude,magnitude_source);
  if (status != MagickFalse)
    status=ForwardQuadrantSwap(fourier_info->height,fourier_info->height,phase,
      phase_source);
  CorrectPhaseLHS(fourier_info->height,fourier_info->height,phase_source);
  if (fourier_info->modulus != MagickFalse)
    {
      i=0L;
      for (y=0L; y < (ssize_t) fourier_info->height; y++)
        for (x=0L; x < (ssize_t) fourier_info->width; x++)
        {
          phase_source[i]/=(2.0*MagickPI);
          phase_source[i]+=0.5;
          i++;
        }
    }
  magnitude_view=AcquireAuthenticCacheView(magnitude_image,exception);
  i=0L;
  for (y=0L; y < (ssize_t) fourier_info->height; y++)
  {
    q=GetCacheViewAuthenticPixels(magnitude_view,0L,y,fourier_info->height,1UL,
      exception);
    if (q == (PixelPacket *) NULL)
      break;
    indexes=GetCacheViewAuthenticIndexQueue(magnitude_view);
    for (x=0L; x < (ssize_t) fourier_info->width; x++)
    {
      switch (fourier_info->channel)
      {
        case RedChannel:
        default:
        {
          SetPixelRed(q,ClampToQuantum(QuantumRange*
            magnitude_source[i]));
          break;
        }
        case GreenChannel:
        {
          SetPixelGreen(q,ClampToQuantum(QuantumRange*
            magnitude_source[i]));
          break;
        }
        case BlueChannel:
        {
          SetPixelBlue(q,ClampToQuantum(QuantumRange*
            magnitude_source[i]));
          break;
        }
        case OpacityChannel:
        {
          SetPixelOpacity(q,ClampToQuantum(QuantumRange*
            magnitude_source[i]));
          break;
        }
        case IndexChannel:
        {
          SetPixelIndex(indexes+x,ClampToQuantum(QuantumRange*
            magnitude_source[i]));
          break;
        }
        case GrayChannels:
        {
          SetPixelGray(q,ClampToQuantum(QuantumRange*
            magnitude_source[i]));
          break;
        }
      }
      i++;
      q++;
    }
    status=SyncCacheViewAuthenticPixels(magnitude_view,exception);
    if (status == MagickFalse)
      break;
  }
  magnitude_view=DestroyCacheView(magnitude_view);
  i=0L;
  phase_view=AcquireAuthenticCacheView(phase_image,exception);
  for (y=0L; y < (ssize_t) fourier_info->height; y++)
  {
    q=GetCacheViewAuthenticPixels(phase_view,0L,y,fourier_info->height,1UL,
      exception);
    if (q == (PixelPacket *) NULL)
      break;
    indexes=GetCacheViewAuthenticIndexQueue(phase_view);
    for (x=0L; x < (ssize_t) fourier_info->width; x++)
    {
      switch (fourier_info->channel)
      {
        case RedChannel:
        default:
        {
          SetPixelRed(q,ClampToQuantum(QuantumRange*phase_source[i]));
          break;
        }
        case GreenChannel:
        {
          SetPixelGreen(q,ClampToQuantum(QuantumRange*phase_source[i]));
          break;
        }
        case BlueChannel:
        {
          SetPixelBlue(q,ClampToQuantum(QuantumRange*phase_source[i]));
          break;
        }
        case OpacityChannel:
        {
          SetPixelOpacity(q,ClampToQuantum(QuantumRange*phase_source[i]));
          break;
        }
        case IndexChannel:
        {
          SetPixelIndex(indexes+x,ClampToQuantum(QuantumRange*phase_source[i]));
          break;
        }
        case GrayChannels:
        {
          SetPixelGray(q,ClampToQuantum(QuantumRange*phase_source[i]));
          break;
        }
      }
      i++;
      q++;
    }
    status=SyncCacheViewAuthenticPixels(phase_view,exception);
    if (status == MagickFalse)
      break;
   }
  phase_view=DestroyCacheView(phase_view);
  phase_source=(double *) RelinquishMagickMemory(phase_source);
  magnitude_source=(double *) RelinquishMagickMemory(magnitude_source);
  return(status);
}
示例#11
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d H A L D I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadHALDImage() creates a Hald color lookup table image and returns it.  It
%  allocates the memory necessary for the new Image structure and returns a
%  pointer to the new image.
%
%  The format of the ReadHALDImage method is:
%
%      Image *ReadHALDImage(const ImageInfo *image_info,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadHALDImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  Image
    *image;

  MagickBooleanType
    status;

  size_t
    cube_size,
    level;

  ssize_t
    y;

  /*
    Create HALD color lookup table image.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AcquireImage(image_info);
  level=0;
  if (*image_info->filename != '\0')
    level=StringToUnsignedLong(image_info->filename);
  if (level < 2)
    level=8;
  status=MagickTrue;
  cube_size=level*level;
  image->columns=(size_t) (level*cube_size);
  image->rows=(size_t) (level*cube_size);
  for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) level)
  {
    ssize_t
      blue,
      green,
      red;

    register PixelPacket
      *restrict q;

    if (status == MagickFalse)
      continue;
    q=QueueAuthenticPixels(image,0,y,image->columns,(size_t) level,
      exception);
    if (q == (PixelPacket *) NULL)
      {
        status=MagickFalse;
        continue;
      }
    blue=y/(ssize_t) level;
    for (green=0; green < (ssize_t) cube_size; green++)
    {
      for (red=0; red < (ssize_t) cube_size; red++)
      {
        SetPixelRed(q,ClampToQuantum(QuantumRange*red/
          (cube_size-1.0)));
        SetPixelGreen(q,ClampToQuantum(QuantumRange*green/
          (cube_size-1.0)));
        SetPixelBlue(q,ClampToQuantum(QuantumRange*blue/
          (cube_size-1.0)));
        SetPixelOpacity(q,OpaqueOpacity);
        q++;
      }
    }
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      status=MagickFalse;
  }
  return(GetFirstImageInList(image));
}
示例#12
0
MagickExport MagickBooleanType OpaquePaintImageChannel(Image *image,
  const ChannelType channel,const MagickPixelPacket *target,
  const MagickPixelPacket *fill,const MagickBooleanType invert)
{
#define OpaquePaintImageTag  "Opaque/Image"

  CacheView
    *image_view;

  ExceptionInfo
    *exception;

  MagickBooleanType
    status;

  MagickOffsetType
    progress;

  MagickPixelPacket
    zero;

  ssize_t
    y;

  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  assert(target != (MagickPixelPacket *) NULL);
  assert(fill != (MagickPixelPacket *) NULL);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
    return(MagickFalse);
  if ((IsGrayColorspace(image->colorspace) != MagickFalse) &&
      (IsMagickGray(fill) != MagickFalse))
    (void) TransformImageColorspace(image,sRGBColorspace);
  if ((fill->opacity != OpaqueOpacity) && (image->matte == MagickFalse))
    (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
  /*
    Make image color opaque.
  */
  status=MagickTrue;
  progress=0;
  exception=(&image->exception);
  GetMagickPixelPacket(image,&zero);
  image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(static,4) shared(progress,status) \
    IsConcurrentDos(image->columns,image->rows,64)
#endif
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    MagickPixelPacket
      pixel;

    register IndexPacket
      *restrict indexes;

    register ssize_t
      x;

    register PixelPacket
      *restrict q;

    if (status == MagickFalse)
      continue;
    q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
    if (q == (PixelPacket *) NULL)
      {
        status=MagickFalse;
        continue;
      }
    indexes=GetCacheViewAuthenticIndexQueue(image_view);
    pixel=zero;
    for (x=0; x < (ssize_t) image->columns; x++)
    {
      SetMagickPixelPacket(image,q,indexes+x,&pixel);
      if (IsMagickColorSimilar(&pixel,target) != invert)
        {
          if ((channel & RedChannel) != 0)
            SetPixelRed(q,ClampToQuantum(fill->red));
          if ((channel & GreenChannel) != 0)
            SetPixelGreen(q,ClampToQuantum(fill->green));
          if ((channel & BlueChannel) != 0)
            SetPixelBlue(q,ClampToQuantum(fill->blue));
          if ((channel & OpacityChannel) != 0)
            SetPixelOpacity(q,ClampToQuantum(fill->opacity));
          if (((channel & IndexChannel) != 0) &&
              (image->colorspace == CMYKColorspace))
            SetPixelIndex(indexes+x,ClampToQuantum(fill->index));
        }
      q++;
    }
    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
      status=MagickFalse;
    if (image->progress_monitor != (MagickProgressMonitor) NULL)
      {
        MagickBooleanType
          proceed;

#if defined(MAGICKCORE_OPENMP_SUPPORT)
        #pragma omp critical (MagickCore_OpaquePaintImageChannel)
#endif
        proceed=SetImageProgress(image,OpaquePaintImageTag,progress++,
          image->rows);
        if (proceed == MagickFalse)
          status=MagickFalse;
      }
  }
  image_view=DestroyCacheView(image_view);
  return(status);
}
示例#13
0
static MagickBooleanType InverseFourierTransform(FourierInfo *fourier_info,
  fftw_complex *fourier,Image *image,ExceptionInfo *exception)
{
  CacheView
    *image_view;

  double
    *source;

  fftw_plan
    fftw_c2r_plan;

  register IndexPacket
    *indexes;

  register PixelPacket
    *q;

  register ssize_t
    i,
    x;

  ssize_t
    y;

  source=(double *) AcquireQuantumMemory((size_t) fourier_info->height,
    fourier_info->width*sizeof(*source));
  if (source == (double *) NULL)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),
        ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
      return(MagickFalse);
    }
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp critical (MagickCore_InverseFourierTransform)
#endif
  {
    fftw_c2r_plan=fftw_plan_dft_c2r_2d(fourier_info->width,fourier_info->height,
      fourier,source,FFTW_ESTIMATE);
    fftw_execute(fftw_c2r_plan);
    fftw_destroy_plan(fftw_c2r_plan);
  }
  i=0L;
  image_view=AcquireAuthenticCacheView(image,exception);
  for (y=0L; y < (ssize_t) fourier_info->height; y++)
  {
    if (y >= (ssize_t) image->rows)
      break;
    q=GetCacheViewAuthenticPixels(image_view,0L,y,fourier_info->width >
      image->columns ? image->columns : fourier_info->width,1UL,exception);
    if (q == (PixelPacket *) NULL)
      break;
    indexes=GetCacheViewAuthenticIndexQueue(image_view);
    for (x=0L; x < (ssize_t) fourier_info->width; x++)
    {
      if (x < (ssize_t) image->columns)
        switch (fourier_info->channel)
        {
          case RedChannel:
          default:
          {
            SetPixelRed(q,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
          case GreenChannel:
          {
            SetPixelGreen(q,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
          case BlueChannel:
          {
            SetPixelBlue(q,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
          case OpacityChannel:
          {
            SetPixelOpacity(q,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
          case IndexChannel:
          {
            SetPixelIndex(indexes+x,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
          case GrayChannels:
          {
            SetPixelGray(q,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
        }
      i++;
      q++;
    }
    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
      break;
  }
  image_view=DestroyCacheView(image_view);
  source=(double *) RelinquishMagickMemory(source);
  return(MagickTrue);
}
示例#14
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%     C o m b i n e I m a g e s                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  CombineImages() combines one or more images into a single image.  The
%  grayscale value of the pixels of each image in the sequence is assigned in
%  order to the specified channels of the combined image.   The typical
%  ordering would be image 1 => Red, 2 => Green, 3 => Blue, etc.
%
%  The format of the CombineImages method is:
%
%      Image *CombineImages(const Image *image,const ChannelType channel,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport Image *CombineImages(const Image *image,const ChannelType channel,
  ExceptionInfo *exception)
{
#define CombineImageTag  "Combine/Image"

  CacheView
    *combine_view;

  const Image
    *next;

  Image
    *combine_image;

  MagickBooleanType
    status;

  MagickOffsetType
    progress;

  ssize_t
    y;

  /*
    Ensure the image are the same size.
  */
  assert(image != (const Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
  {
    if ((next->columns != image->columns) || (next->rows != image->rows))
      ThrowImageException(OptionError,"ImagesAreNotTheSameSize");
  }
  combine_image=CloneImage(image,0,0,MagickTrue,exception);
  if (combine_image == (Image *) NULL)
    return((Image *) NULL);
  if (SetImageStorageClass(combine_image,DirectClass) == MagickFalse)
    {
      InheritException(exception,&combine_image->exception);
      combine_image=DestroyImage(combine_image);
      return((Image *) NULL);
    }
  if (IssRGBCompatibleColorspace(image->colorspace) != MagickFalse)
    (void) SetImageColorspace(combine_image,sRGBColorspace);
  if ((channel & OpacityChannel) != 0)
    combine_image->matte=MagickTrue;
  (void) SetImageBackgroundColor(combine_image);
  /*
    Combine images.
  */
  status=MagickTrue;
  progress=0;
  combine_view=AcquireAuthenticCacheView(combine_image,exception);
  for (y=0; y < (ssize_t) combine_image->rows; y++)
  {
    CacheView
      *image_view;

    const Image
      *next;

    PixelPacket
      *pixels;

    register const PixelPacket
      *restrict p;

    register PixelPacket
      *restrict q;

    register ssize_t
      x;

    if (status == MagickFalse)
      continue;
    pixels=GetCacheViewAuthenticPixels(combine_view,0,y,combine_image->columns,
      1,exception);
    if (pixels == (PixelPacket *) NULL)
      {
        status=MagickFalse;
        continue;
      }
    next=image;
    if (((channel & RedChannel) != 0) && (next != (Image *) NULL))
      {
        image_view=AcquireVirtualCacheView(next,exception);
        p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
        if (p == (const PixelPacket *) NULL)
          continue;
        q=pixels;
        for (x=0; x < (ssize_t) combine_image->columns; x++)
        {
          SetPixelRed(q,ClampToQuantum(GetPixelIntensity(image,p)));
          p++;
          q++;
        }
        image_view=DestroyCacheView(image_view);
        next=GetNextImageInList(next);
      }
    if (((channel & GreenChannel) != 0) && (next != (Image *) NULL))
      {
        image_view=AcquireVirtualCacheView(next,exception);
        p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
        if (p == (const PixelPacket *) NULL)
          continue;
        q=pixels;
        for (x=0; x < (ssize_t) combine_image->columns; x++)
        {
          SetPixelGreen(q,ClampToQuantum(GetPixelIntensity(image,p)));
          p++;
          q++;
        }
        image_view=DestroyCacheView(image_view);
        next=GetNextImageInList(next);
      }
    if (((channel & BlueChannel) != 0) && (next != (Image *) NULL))
      {
        image_view=AcquireVirtualCacheView(next,exception);
        p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
        if (p == (const PixelPacket *) NULL)
          continue;
        q=pixels;
        for (x=0; x < (ssize_t) combine_image->columns; x++)
        {
          SetPixelBlue(q,ClampToQuantum(GetPixelIntensity(image,p)));
          p++;
          q++;
        }
        image_view=DestroyCacheView(image_view);
        next=GetNextImageInList(next);
      }
    if (((channel & OpacityChannel) != 0) && (next != (Image *) NULL))
      {
        image_view=AcquireVirtualCacheView(next,exception);
        p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
        if (p == (const PixelPacket *) NULL)
          continue;
        q=pixels;
        for (x=0; x < (ssize_t) combine_image->columns; x++)
        {
          SetPixelAlpha(q,ClampToQuantum(GetPixelIntensity(image,p)));
          p++;
          q++;
        }
        image_view=DestroyCacheView(image_view);
        next=GetNextImageInList(next);
      }
    if (((channel & IndexChannel) != 0) &&
        (image->colorspace == CMYKColorspace) && (next != (Image *) NULL))
      {
        IndexPacket
          *indexes;

        image_view=AcquireVirtualCacheView(next,exception);
        p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
        if (p == (const PixelPacket *) NULL)
          continue;
        indexes=GetCacheViewAuthenticIndexQueue(combine_view);
        for (x=0; x < (ssize_t) combine_image->columns; x++)
        {
          SetPixelIndex(indexes+x,ClampToQuantum(GetPixelIntensity(image,p)));
          p++;
        }
        image_view=DestroyCacheView(image_view);
        next=GetNextImageInList(next);
      }
    if (SyncCacheViewAuthenticPixels(combine_view,exception) == MagickFalse)
      status=MagickFalse;
    if (image->progress_monitor != (MagickProgressMonitor) NULL)
      {
        MagickBooleanType
          proceed;

        proceed=SetImageProgress(image,CombineImageTag,progress++,
          combine_image->rows);
        if (proceed == MagickFalse)
          status=MagickFalse;
      }
  }
  combine_view=DestroyCacheView(combine_view);
  if (IsGrayColorspace(combine_image->colorspace) != MagickFalse)
    (void) TransformImageColorspace(combine_image,sRGBColorspace);
  if (status == MagickFalse)
    combine_image=DestroyImage(combine_image);
  return(combine_image);
}
示例#15
0
MagickExport MagickBooleanType SeparateImageChannel(Image *image,
  const ChannelType channel)
{
#define SeparateImageTag  "Separate/Image"

  CacheView
    *image_view;

  ExceptionInfo
    *exception;

  MagickBooleanType
    status;

  MagickOffsetType
    progress;

  ssize_t
    y;

  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
    return(MagickFalse);
  if (channel == GrayChannels)
    image->matte=MagickTrue;
  /*
    Separate image channels.
  */
  status=MagickTrue;
  progress=0;
  exception=(&image->exception);
  image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(static,4) shared(progress,status) \
    magick_threads(image,image,image->rows,1)
#endif
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    register IndexPacket
      *restrict indexes;

    register PixelPacket
      *restrict q;

    register ssize_t
      x;

    if (status == MagickFalse)
      continue;
    q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
    if (q == (PixelPacket *) NULL)
      {
        status=MagickFalse;
        continue;
      }
    indexes=GetCacheViewAuthenticIndexQueue(image_view);
    switch (channel)
    {
      case RedChannel:
      {
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          SetPixelGreen(q,GetPixelRed(q));
          SetPixelBlue(q,GetPixelRed(q));
          q++;
        }
        break;
      }
      case GreenChannel:
      {
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          SetPixelRed(q,GetPixelGreen(q));
          SetPixelBlue(q,GetPixelGreen(q));
          q++;
        }
        break;
      }
      case BlueChannel:
      {
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          SetPixelRed(q,GetPixelBlue(q));
          SetPixelGreen(q,GetPixelBlue(q));
          q++;
        }
        break;
      }
      case OpacityChannel:
      {
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          SetPixelRed(q,GetPixelOpacity(q));
          SetPixelGreen(q,GetPixelOpacity(q));
          SetPixelBlue(q,GetPixelOpacity(q));
          q++;
        }
        break;
      }
      case BlackChannel:
      {
        if ((image->storage_class != PseudoClass) &&
            (image->colorspace != CMYKColorspace))
          break;
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          SetPixelRed(q,GetPixelIndex(indexes+x));
          SetPixelGreen(q,GetPixelIndex(indexes+x));
          SetPixelBlue(q,GetPixelIndex(indexes+x));
          q++;
        }
        break;
      }
      case TrueAlphaChannel:
      {
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          SetPixelRed(q,GetPixelAlpha(q));
          SetPixelGreen(q,GetPixelAlpha(q));
          SetPixelBlue(q,GetPixelAlpha(q));
          q++;
        }
        break;
      }
      case GrayChannels:
      {
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          SetPixelAlpha(q,ClampToQuantum(GetPixelIntensity(image,q)));
          q++;
        }
        break;
      }
      default:
        break;
    }
    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
      status=MagickFalse;
    if (image->progress_monitor != (MagickProgressMonitor) NULL)
      {
        MagickBooleanType
          proceed;

#if defined(MAGICKCORE_OPENMP_SUPPORT)
        #pragma omp critical (MagickCore_SeparateImageChannel)
#endif
        proceed=SetImageProgress(image,SeparateImageTag,progress++,image->rows);
        if (proceed == MagickFalse)
          status=MagickFalse;
      }
  }
  image_view=DestroyCacheView(image_view);
  if (channel != GrayChannels)
    image->matte=MagickFalse;
  (void) SetImageColorspace(image,GRAYColorspace);
  return(status);
}
示例#16
0
MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
  const AlphaChannelOption alpha_type,ExceptionInfo *exception)
{
  CacheView
    *image_view;

  MagickBooleanType
    status;

  ssize_t
    y;

  assert(image != (Image *) NULL);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  assert(image->signature == MagickSignature);
  status=MagickTrue;
  switch (alpha_type)
  {
    case ActivateAlphaChannel:
    {
      image->alpha_trait=BlendPixelTrait;
      break;
    }
    case AssociateAlphaChannel:
    {
      /*
        Associate alpha.
      */
      status=SetImageStorageClass(image,DirectClass,exception);
      if (status == MagickFalse)
        break;
      image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
      #pragma omp parallel for schedule(static,4) shared(status) \
        magick_threads(image,image,image->rows,1)
#endif
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        register Quantum
          *restrict q;

        register ssize_t
          x;

        if (status == MagickFalse)
          continue;
        q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
          exception);
        if (q == (Quantum *) NULL)
          {
            status=MagickFalse;
            continue;
          }
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          double
            Sa;
  
          register ssize_t
            i;
  
          if (GetPixelReadMask(image,q) == 0)
            {
              q+=GetPixelChannels(image);
              continue;
            }
          Sa=QuantumScale*GetPixelAlpha(image,q);
          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
          {
            PixelChannel channel=GetPixelChannelChannel(image,i);
            PixelTrait traits=GetPixelChannelTraits(image,channel);
            if ((traits & UpdatePixelTrait) == 0)
              continue;
            q[i]=ClampToQuantum(Sa*q[i]);
          }
          q+=GetPixelChannels(image);
        }
        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
          status=MagickFalse;
      }
      image_view=DestroyCacheView(image_view);
      image->alpha_trait=CopyPixelTrait;
      return(status);
    }
    case BackgroundAlphaChannel:
    {
      /*
        Set transparent pixels to background color.
      */
      if (image->alpha_trait != BlendPixelTrait)
        break;
      status=SetImageStorageClass(image,DirectClass,exception);
      if (status == MagickFalse)
        break;
      image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
      #pragma omp parallel for schedule(static,4) shared(status) \
        magick_threads(image,image,image->rows,1)
#endif
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        register Quantum
          *restrict q;

        register ssize_t
          x;

        if (status == MagickFalse)
          continue;
        q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
          exception);
        if (q == (Quantum *) NULL)
          {
            status=MagickFalse;
            continue;
          }
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          if (GetPixelAlpha(image,q) == TransparentAlpha)
            {
              SetPixelInfoPixel(image,&image->background_color,q);
              SetPixelChannel(image,AlphaPixelChannel,TransparentAlpha,q);
            }
          q+=GetPixelChannels(image);
        }
        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
          status=MagickFalse;
      }
      image_view=DestroyCacheView(image_view);
      return(status);
    }
    case CopyAlphaChannel:
    case ShapeAlphaChannel:
    {
      /*
        Copy pixel intensity to the alpha channel.
      */
      status=CompositeImage(image,image,IntensityCompositeOp,MagickTrue,0,0,
        exception);
      if (alpha_type == ShapeAlphaChannel)
        (void) LevelImageColors(image,&image->background_color,
          &image->background_color,MagickTrue,exception);
      break;
    }
    case DeactivateAlphaChannel:
    {
      image->alpha_trait=CopyPixelTrait;
      break;
    }
    case DisassociateAlphaChannel:
    {
      /*
        Disassociate alpha.
      */
      status=SetImageStorageClass(image,DirectClass,exception);
      if (status == MagickFalse)
        break;
      image->alpha_trait=BlendPixelTrait;
      image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
      #pragma omp parallel for schedule(static,4) shared(status) \
        magick_threads(image,image,image->rows,1)
#endif
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        register Quantum
          *restrict q;

        register ssize_t
          x;

        if (status == MagickFalse)
          continue;
        q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
          exception);
        if (q == (Quantum *) NULL)
          {
            status=MagickFalse;
            continue;
          }
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          double
            gamma, 
            Sa;

          register ssize_t
            i;

          if (GetPixelReadMask(image,q) == 0)
            {
              q+=GetPixelChannels(image);
              continue;
            }
          Sa=QuantumScale*GetPixelAlpha(image,q);
          gamma=PerceptibleReciprocal(Sa);
          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
          {
            PixelChannel channel=GetPixelChannelChannel(image,i);
            PixelTrait traits=GetPixelChannelTraits(image,channel);
            if ((traits & UpdatePixelTrait) == 0)
              continue;
            q[i]=ClampToQuantum(gamma*q[i]);
          }
          q+=GetPixelChannels(image);
        }
        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
          status=MagickFalse;
      }
      image_view=DestroyCacheView(image_view);
      return(status);
    }
    case DiscreteAlphaChannel:
    {
      image->alpha_trait=UpdatePixelTrait;
      break;
    }
    case ExtractAlphaChannel:
    {
      status=CompositeImage(image,image,AlphaCompositeOp,MagickTrue,0,0,
        exception);
      image->alpha_trait=CopyPixelTrait;
      break;
    }
    case OpaqueAlphaChannel:
    {
      status=SetImageAlpha(image,OpaqueAlpha,exception);
      break;
    }
    case RemoveAlphaChannel:
    {
      /*
        Remove transparency.
      */
      if (image->alpha_trait != BlendPixelTrait)
        break;
      status=SetImageStorageClass(image,DirectClass,exception);
      if (status == MagickFalse)
        break;
      image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
      #pragma omp parallel for schedule(static,4) shared(status) \
        magick_threads(image,image,image->rows,1)
#endif
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        register Quantum
          *restrict q;

        register ssize_t
          x;

        if (status == MagickFalse)
          continue;
        q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
          exception);
        if (q == (Quantum *) NULL)
          {
            status=MagickFalse;
            continue;
          }
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          FlattenPixelInfo(image,&image->background_color,
            image->background_color.alpha,q,(double)
            GetPixelAlpha(image,q),q);
          q+=GetPixelChannels(image);
        }
        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
          status=MagickFalse;
      }
      image_view=DestroyCacheView(image_view);
      image->alpha_trait=image->background_color.alpha_trait;
      return(status);
    }
    case SetAlphaChannel:
    {
      if (image->alpha_trait != BlendPixelTrait)
        status=SetImageAlpha(image,OpaqueAlpha,exception);
      break;
    }
    case TransparentAlphaChannel:
    {
      status=SetImageAlpha(image,TransparentAlpha,exception);
      break;
    }
    case UndefinedAlphaChannel:
      break;
  }
  if (status == MagickFalse)
    return(status);
  return(SyncImagePixelCache(image,exception));
}
示例#17
0
文件: hdr.c 项目: INT2208-ST/MyFriend
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d H D R I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadHDRImage() reads the Radiance RGBE image format and returns it.  It
%  allocates the memory necessary for the new Image structure and returns a
%  pointer to the new image.
%
%  The format of the ReadHDRImage method is:
%
%      Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  char
    format[MaxTextExtent],
    keyword[MaxTextExtent],
    tag[MaxTextExtent],
    value[MaxTextExtent];

  double
    gamma;

  Image
    *image;

  int
    c;

  MagickBooleanType
    status,
    value_expected;

  register PixelPacket
    *q;

  register unsigned char
    *p;

  register ssize_t
    i,
    x;

  ssize_t
    count,
    y;

  unsigned char
    *end,
    pixel[4],
    *pixels;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AcquireImage(image_info);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
    Decode image header.
  */
  image->columns=0;
  image->rows=0;
  *format='\0';
  c=ReadBlobByte(image);
  if (c == EOF)
    {
      image=DestroyImage(image);
      return((Image *) NULL);
    }
  while (isgraph(c) && (image->columns == 0) && (image->rows == 0))
  {
    if (c == (int) '#')
      {
        char
          *comment;

        register char
          *p;

        size_t
          length;

        /*
          Read comment-- any text between # and end-of-line.
        */
        length=MaxTextExtent;
        comment=AcquireString((char *) NULL);
        for (p=comment; comment != (char *) NULL; p++)
        {
          c=ReadBlobByte(image);
          if ((c == EOF) || (c == (int) '\n'))
            break;
          if ((size_t) (p-comment+1) >= length)
            {
              *p='\0';
              length<<=1;
              comment=(char *) ResizeQuantumMemory(comment,length+
                MaxTextExtent,sizeof(*comment));
              if (comment == (char *) NULL)
                break;
              p=comment+strlen(comment);
            }
          *p=(char) c;
        }
        if (comment == (char *) NULL)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        *p='\0';
        (void) SetImageProperty(image,"comment",comment);
        comment=DestroyString(comment);
        c=ReadBlobByte(image);
      }
    else
      if (isalnum(c) == MagickFalse)
        c=ReadBlobByte(image);
      else
        {
          register char
            *p;

          /*
            Determine a keyword and its value.
          */
          p=keyword;
          do
          {
            if ((size_t) (p-keyword) < (MaxTextExtent-1))
              *p++=c;
            c=ReadBlobByte(image);
          } while (isalnum(c) || (c == '_'));
          *p='\0';
          value_expected=MagickFalse;
          while ((isspace((int) ((unsigned char) c)) != 0) || (c == '='))
          {
            if (c == '=')
              value_expected=MagickTrue;
            c=ReadBlobByte(image);
          }
          if (LocaleCompare(keyword,"Y") == 0)
            value_expected=MagickTrue;
          if (value_expected == MagickFalse)
            continue;
          p=value;
          while ((c != '\n') && (c != '\0') && (c != EOF))
          {
            if ((size_t) (p-value) < (MaxTextExtent-1))
              *p++=c;
            c=ReadBlobByte(image);
          }
          *p='\0';
          /*
            Assign a value to the specified keyword.
          */
          switch (*keyword)
          {
            case 'F':
            case 'f':
            {
              if (LocaleCompare(keyword,"format") == 0)
                {
                  (void) CopyMagickString(format,value,MaxTextExtent);
                  break;
                }
              (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
              (void) SetImageProperty(image,tag,value);
              break;
            }
            case 'G':
            case 'g':
            {
              if (LocaleCompare(keyword,"gamma") == 0)
                {
                  image->gamma=StringToDouble(value,(char **) NULL);
                  break;
                }
              (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
              (void) SetImageProperty(image,tag,value);
              break;
            }
            case 'P':
            case 'p':
            {
              if (LocaleCompare(keyword,"primaries") == 0)
                {
                  float
                    chromaticity[6],
                    white_point[2];

                  int
                    count;

                  count=sscanf(value,"%g %g %g %g %g %g %g %g",&chromaticity[0],
                    &chromaticity[1],&chromaticity[2],&chromaticity[3],
                    &chromaticity[4],&chromaticity[5],&white_point[0],
                    &white_point[1]);
                  if (count == 8)
                    {
                      image->chromaticity.red_primary.x=chromaticity[0];
                      image->chromaticity.red_primary.y=chromaticity[1];
                      image->chromaticity.green_primary.x=chromaticity[2];
                      image->chromaticity.green_primary.y=chromaticity[3];
                      image->chromaticity.blue_primary.x=chromaticity[4];
                      image->chromaticity.blue_primary.y=chromaticity[5];
                      image->chromaticity.white_point.x=white_point[0],
                      image->chromaticity.white_point.y=white_point[1];
                    }
                  break;
                }
              (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
              (void) SetImageProperty(image,tag,value);
              break;
            }
            case 'Y':
            case 'y':
            {
              char
                target[] = "Y";

              if (strcmp(keyword,target) == 0)
                {
                  int
                    height,
                    width;

                  if (sscanf(value,"%d +X %d",&height,&width) == 2)
                    {
                      image->columns=(size_t) width;
                      image->rows=(size_t) height;
                    }
                  break;
                }
              (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
              (void) SetImageProperty(image,tag,value);
              break;
            }
            default:
            {
              (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
              (void) SetImageProperty(image,tag,value);
              break;
            }
          }
        }
    if ((image->columns == 0) && (image->rows == 0))
      while (isspace((int) ((unsigned char) c)) != 0)
        c=ReadBlobByte(image);
  }
  if ((LocaleCompare(format,"32-bit_rle_rgbe") != 0) &&
      (LocaleCompare(format,"32-bit_rle_xyze") != 0))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  if ((image->columns == 0) || (image->rows == 0))
    ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
  (void) SetImageColorspace(image,RGBColorspace);
  if (LocaleCompare(format,"32-bit_rle_xyze") == 0)
    (void) SetImageColorspace(image,XYZColorspace);
  image->compression=(image->columns < 8) || (image->columns > 0x7ffff) ?
    NoCompression : RLECompression;
  if (image_info->ping != MagickFalse)
    {
      (void) CloseBlob(image);
      return(GetFirstImageInList(image));
    }
  status=SetImageExtent(image,image->columns,image->rows);
  if (status == MagickFalse)
    {
      InheritException(exception,&image->exception);
      return(DestroyImageList(image));
    }
  /*
    Read RGBE (red+green+blue+exponent) pixels.
  */
  pixels=(unsigned char *) AcquireQuantumMemory(image->columns,4*
    sizeof(*pixels));
  if (pixels == (unsigned char *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    if (image->compression != RLECompression)
      {
        count=ReadBlob(image,4*image->columns*sizeof(*pixels),pixels);
        if (count != (ssize_t) (4*image->columns*sizeof(*pixels)))
          break;
      }
    else
      {
        count=ReadBlob(image,4*sizeof(*pixel),pixel);
        if (count != 4)
          break;
        if ((size_t) ((((size_t) pixel[2]) << 8) | pixel[3]) != image->columns)
          {
            (void) memcpy(pixels,pixel,4*sizeof(*pixel));
            (void) ReadBlob(image,4*(image->columns-1)*sizeof(*pixels),pixels+4);
            image->compression=NoCompression;
          }
        else
          {
            p=pixels;
            for (i=0; i < 4; i++)
            {
              end=&pixels[(i+1)*image->columns];
              while (p < end)
              {
                count=ReadBlob(image,2*sizeof(*pixel),pixel);
                if (count < 1)
                  break;
                if (pixel[0] > 128)
                  {
                    count=(ssize_t) pixel[0]-128;
                    if ((count == 0) || (count > (ssize_t) (end-p)))
                      break;
                    while (count-- > 0)
                      *p++=pixel[1];
                  }
                else
                  {
                    count=(ssize_t) pixel[0];
                    if ((count == 0) || (count > (ssize_t) (end-p)))
                      break;
                    *p++=pixel[1];
                    if (--count > 0)
                      {
                        count=ReadBlob(image,(size_t) count*sizeof(*p),p);
                        if (count < 1)
                          break;
                        p+=count;
                      }
                  }
              }
            }
          }
      }
    q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    if (q == (PixelPacket *) NULL)
      break;
    i=0;
    for (x=0; x < (ssize_t) image->columns; x++)
    {
      if (image->compression == RLECompression)
        {
          pixel[0]=pixels[x];
          pixel[1]=pixels[x+image->columns];
          pixel[2]=pixels[x+2*image->columns];
          pixel[3]=pixels[x+3*image->columns];
        }
      else
        {
          pixel[0]=pixels[i++];
          pixel[1]=pixels[i++];
          pixel[2]=pixels[i++];
          pixel[3]=pixels[i++];
        }
      SetPixelRed(q,0);
      SetPixelGreen(q,0);
      SetPixelBlue(q,0);
      if (pixel[3] != 0)
        {
          gamma=pow(2.0,pixel[3]-(128.0+8.0));
          SetPixelRed(q,ClampToQuantum(QuantumRange*gamma*pixel[0]));
          SetPixelGreen(q,ClampToQuantum(QuantumRange*gamma*pixel[1]));
          SetPixelBlue(q,ClampToQuantum(QuantumRange*gamma*pixel[2]));
        }
      q++;
    }
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
    status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
      image->rows);
    if (status == MagickFalse)
      break;
  }
  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
  if (EOFBlob(image) != MagickFalse)
    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
      image->filename);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}
示例#18
0
static inline void FlattenPixelInfo(const Image *image,const PixelInfo *p,
  const double alpha,const Quantum *q,const double beta,
  Quantum *composite)
{
  double
    Da,
    gamma,
    Sa;

  register ssize_t
    i;

  /*
    Compose pixel p over pixel q with the given alpha.
  */
  Sa=QuantumScale*alpha;
  Da=QuantumScale*beta,
  gamma=Sa*(-Da)+Sa+Da;
  gamma=PerceptibleReciprocal(gamma);
  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
  {
    PixelChannel channel=GetPixelChannelChannel(image,i);
    PixelTrait traits=GetPixelChannelTraits(image,channel);
    if (traits == UndefinedPixelTrait)
      continue;
    switch (channel)
    {
      case RedPixelChannel:
      {
        composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
          (double) p->red,alpha));
        break;
      }
      case GreenPixelChannel:
      {
        composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
          (double) p->green,alpha));
        break;
      }
      case BluePixelChannel:
      {
        composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
          (double) p->blue,alpha));
        break;
      }
      case BlackPixelChannel:
      {
        composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
          (double) p->black,alpha));
        break;
      }
      case AlphaPixelChannel:
      {
        composite[i]=ClampToQuantum(QuantumRange*(Sa*(-Da)+Sa+Da));
        break;
      }
      default:
        break;
    }
  }
}
示例#19
0
MagickExport Image *ChannelFxImage(const Image *image,const char *expression,
  ExceptionInfo *exception)
{
#define ChannelFxImageTag  "ChannelFx/Image"

  ChannelFx
    channel_op;

  ChannelType
    channel_mask;

  char
    token[MaxTextExtent];

  const char
    *p;

  const Image
    *source_image;

  double
    pixel;

  Image
    *destination_image;

  MagickBooleanType
    status;

  PixelChannel
    source_channel,
    destination_channel;

  ssize_t
    channels;

  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  source_image=image;
  destination_image=CloneImage(source_image,0,0,MagickTrue,exception);
  if (destination_image == (Image *) NULL)
    return((Image *) NULL);
  if (expression == (const char *) NULL)
    return(destination_image);
  destination_channel=RedPixelChannel;
  channel_mask=UndefinedChannel;
  pixel=0.0;
  p=(char *) expression;
  GetMagickToken(p,&p,token);
  channel_op=ExtractChannelOp;
  for (channels=0; *token != '\0'; )
  {
    ssize_t
      i;

    /*
      Interpret channel expression.
    */
    switch (*token)
    {
      case ',':
      {
        GetMagickToken(p,&p,token);
        break;
      }
      case '|':
      {
        if (GetNextImageInList(source_image) != (Image *) NULL)
          source_image=GetNextImageInList(source_image);
        else
          source_image=GetFirstImageInList(source_image);
        GetMagickToken(p,&p,token);
        break;
      }
      case ';':
      {
        Image
          *canvas;

        SetPixelChannelMask(destination_image,channel_mask);
        if ((channel_op == ExtractChannelOp) && (channels == 1))
          (void) SetImageColorspace(destination_image,GRAYColorspace,exception);
        status=SetImageStorageClass(destination_image,DirectClass,exception);
        if (status == MagickFalse)
          {
            destination_image=DestroyImageList(destination_image);
            return(destination_image);
          }
        canvas=CloneImage(source_image,0,0,MagickTrue,exception);
        if (canvas == (Image *) NULL)
          {
            destination_image=DestroyImageList(destination_image);
            return(destination_image);
          }
        AppendImageToList(&destination_image,canvas);
        destination_image=GetLastImageInList(destination_image);
        GetMagickToken(p,&p,token);
        channels=0;
        destination_channel=RedPixelChannel;
        channel_mask=UndefinedChannel;
        break;
      }
      default:
        break;
    }
    i=ParsePixelChannelOption(token);
    if (i < 0)
      {
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
          "UnrecognizedChannelType","`%s'",token);
        destination_image=DestroyImageList(destination_image);
        return(destination_image);
      }
    source_channel=(PixelChannel) i;
    channel_op=ExtractChannelOp;
    GetMagickToken(p,&p,token);
    if (*token == '<')
      {
        channel_op=ExchangeChannelOp;
        GetMagickToken(p,&p,token);
      }
    if (*token == '=')
      {
        if (channel_op != ExchangeChannelOp)
          channel_op=AssignChannelOp;
        GetMagickToken(p,&p,token);
      }
    if (*token == '>')
      {
        if (channel_op != ExchangeChannelOp)
          channel_op=TransferChannelOp;
        GetMagickToken(p,&p,token);
      }
    switch (channel_op)
    {
      case AssignChannelOp:
      {
        pixel=StringToDoubleInterval(token,(double) QuantumRange+1.0);
        GetMagickToken(p,&p,token);
        break;
      }
      case ExchangeChannelOp:
      case TransferChannelOp:
      {
        i=ParsePixelChannelOption(token);
        if (i < 0)
          {
            (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
              "UnrecognizedChannelType","`%s'",token);
            destination_image=DestroyImageList(destination_image);
            return(destination_image);
          }
        destination_channel=(PixelChannel) i;
        switch (destination_channel)
        {
          case RedPixelChannel:
          case GreenPixelChannel:
          case BluePixelChannel:
          case BlackPixelChannel:
          case IndexPixelChannel:
            break;
          case AlphaPixelChannel:
          {
            destination_image->alpha_trait=BlendPixelTrait;
            break;
          }
          case ReadMaskPixelChannel:
          {
            destination_image->read_mask=MagickTrue;
            break;
          }
          case WriteMaskPixelChannel:
          {
            destination_image->write_mask=MagickTrue;
            break;
          }
          case MetaPixelChannel:
          default:
          {
            (void) SetPixelMetaChannels(destination_image,(size_t) (i-
              GetPixelChannels(destination_image)+1),exception);
            break;
          }
        }
        channel_mask=(ChannelType) (channel_mask | ParseChannelOption(token));
        if (((channels >= 1)  || (destination_channel >= 1)) &&
            (IsGrayColorspace(destination_image->colorspace) != MagickFalse))
          (void) SetImageColorspace(destination_image,sRGBColorspace,exception);
        GetMagickToken(p,&p,token);
        break;
      }
      default:
        break;
    }
    status=ChannelImage(destination_image,destination_channel,channel_op,
      source_image,source_channel,ClampToQuantum(pixel),exception);
    if (status == MagickFalse)
      {
        destination_image=DestroyImageList(destination_image);
        break;
      }
    channels++;
    if (channel_op == ExchangeChannelOp)
      {
        status=ChannelImage(destination_image,source_channel,channel_op,
          source_image,destination_channel,ClampToQuantum(pixel),exception);
        if (status == MagickFalse)
          {
            destination_image=DestroyImageList(destination_image);
            break;
          }
        channels++;
      }
    switch (channel_op)
    {
      case ExtractChannelOp:
      {
        channel_mask=(ChannelType) (channel_mask | (1 << destination_channel));
        destination_channel=(PixelChannel) (destination_channel+1);
        break;
      }
      default:
        break;
    }
    status=SetImageProgress(source_image,ChannelFxImageTag,p-expression,
      strlen(expression));
    if (status == MagickFalse)
      break;
  }
  SetPixelChannelMask(destination_image,channel_mask);
  if ((channel_op == ExtractChannelOp) && (channels == 1))
    (void) SetImageColorspace(destination_image,GRAYColorspace,exception);
  status=SetImageStorageClass(destination_image,DirectClass,exception);
  if (status == MagickFalse)
    {
      destination_image=GetLastImageInList(destination_image);
      return((Image *) NULL);
    }
  return(GetFirstImageInList(destination_image));
}
示例#20
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d R L E I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadRLEImage() reads a run-length encoded Utah Raster Toolkit
%  image file and returns it.  It allocates the memory necessary for the new
%  Image structure and returns a pointer to the new image.
%
%  The format of the ReadRLEImage method is:
%
%      Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
%
*/
static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
#define SkipLinesOp  0x01
#define SetColorOp  0x02
#define SkipPixelsOp  0x03
#define ByteDataOp  0x05
#define RunDataOp  0x06
#define EOFOp  0x07

  char
    magick[12];

  Image
    *image;

  int
    opcode,
    operand,
    status;

  MagickStatusType
    flags;

  MagickSizeType
    number_pixels;

  MemoryInfo
    *pixel_info;

  Quantum
    index;

  register ssize_t
    x;

  register Quantum
    *q;

  register ssize_t
    i;

  register unsigned char
    *p;

  size_t
    bits_per_pixel,
    map_length,
    number_colormaps,
    number_planes,
    number_planes_filled,
    one,
    offset,
    pixel_info_length;

  ssize_t
    count,
    y;

  unsigned char
    background_color[256],
    *colormap,
    pixel,
    plane,
    *pixels;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickCoreSignature);
  image=AcquireImage(image_info,exception);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    return(DestroyImageList(image));
  /*
    Determine if this a RLE file.
  */
  count=ReadBlob(image,2,(unsigned char *) magick);
  if ((count != 2) || (memcmp(magick,"\122\314",2) != 0))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  do
  {
    /*
      Read image header.
    */
    image->page.x=ReadBlobLSBShort(image);
    image->page.y=ReadBlobLSBShort(image);
    image->columns=ReadBlobLSBShort(image);
    image->rows=ReadBlobLSBShort(image);
    flags=(MagickStatusType) ReadBlobByte(image);
    image->alpha_trait=flags & 0x04 ? BlendPixelTrait : UndefinedPixelTrait;
    number_planes=(size_t) ReadBlobByte(image);
    bits_per_pixel=(size_t) ReadBlobByte(image);
    number_colormaps=(size_t) ReadBlobByte(image);
    map_length=(unsigned char) ReadBlobByte(image);
    if (map_length >= 64)
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    one=1;
    map_length=one << map_length;
    if ((number_planes == 0) || (number_planes == 2) ||
        ((flags & 0x04) && (number_colormaps > 254)) || (bits_per_pixel != 8) ||
        (image->columns == 0))
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    if (flags & 0x02)
      {
        /*
          No background color-- initialize to black.
        */
        for (i=0; i < (ssize_t) number_planes; i++)
          background_color[i]=0;
        (void) ReadBlobByte(image);
      }
    else
      {
        /*
          Initialize background color.
        */
        p=background_color;
        for (i=0; i < (ssize_t) number_planes; i++)
          *p++=(unsigned char) ReadBlobByte(image);
      }
    if ((number_planes & 0x01) == 0)
      (void) ReadBlobByte(image);
    if (EOFBlob(image) != MagickFalse)
      {
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
          image->filename);
        break;
      }
    colormap=(unsigned char *) NULL;
    if (number_colormaps != 0)
      {
        /*
          Read image colormaps.
        */
        colormap=(unsigned char *) AcquireQuantumMemory(number_colormaps,
          3*map_length*sizeof(*colormap));
        if (colormap == (unsigned char *) NULL)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        p=colormap;
        for (i=0; i < (ssize_t) number_colormaps; i++)
          for (x=0; x < (ssize_t) map_length; x++)
            *p++=(unsigned char) ScaleShortToQuantum(ReadBlobLSBShort(image));
      }
    if ((flags & 0x08) != 0)
      {
        char
          *comment;

        size_t
          length;

        /*
          Read image comment.
        */
        length=ReadBlobLSBShort(image);
        if (length != 0)
          {
            comment=(char *) AcquireQuantumMemory(length,sizeof(*comment));
            if (comment == (char *) NULL)
              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
            count=ReadBlob(image,length-1,(unsigned char *) comment);
            comment[length-1]='\0';
            (void) SetImageProperty(image,"comment",comment,exception);
            comment=DestroyString(comment);
            if ((length & 0x01) == 0)
              (void) ReadBlobByte(image);
          }
      }
    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    status=SetImageExtent(image,image->columns,image->rows,exception);
    if (status == MagickFalse)
      return(DestroyImageList(image));
    /*
      Allocate RLE pixels.
    */
    if (image->alpha_trait != UndefinedPixelTrait)
      number_planes++;
    number_pixels=(MagickSizeType) image->columns*image->rows;
    number_planes_filled=(number_planes % 2 == 0) ? number_planes :
      number_planes+1;
    if ((number_pixels*number_planes_filled) != (size_t) (number_pixels*
         number_planes_filled))
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    if (image->rows < (image->rows*number_planes_filled*sizeof(*pixels)))
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    pixel_info=AcquireVirtualMemory(image->columns,image->rows*
      number_planes_filled*sizeof(*pixels));
    if (pixel_info == (MemoryInfo *) NULL)
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    pixel_info_length=image->columns*image->rows*number_planes_filled;
    pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
    if ((flags & 0x01) && !(flags & 0x02))
      {
        ssize_t
          j;

        /*
          Set background color.
        */
        p=pixels;
        for (i=0; i < (ssize_t) number_pixels; i++)
        {
          if (image->alpha_trait == UndefinedPixelTrait)
            for (j=0; j < (ssize_t) number_planes; j++)
              *p++=background_color[j];
          else
            {
              for (j=0; j < (ssize_t) (number_planes-1); j++)
                *p++=background_color[j];
              *p++=0;  /* initialize matte channel */
            }
        }
      }
    /*
      Read runlength-encoded image.
    */
    plane=0;
    x=0;
    y=0;
    opcode=ReadBlobByte(image);
    do
    {
      switch (opcode & 0x3f)
      {
        case SkipLinesOp:
        {
          operand=ReadBlobByte(image);
          if (opcode & 0x40)
            operand=(int) ReadBlobLSBShort(image);
          x=0;
          y+=operand;
          break;
        }
        case SetColorOp:
        {
          operand=ReadBlobByte(image);
          plane=(unsigned char) operand;
          if (plane == 255)
            plane=(unsigned char) (number_planes-1);
          x=0;
          break;
        }
        case SkipPixelsOp:
        {
          operand=ReadBlobByte(image);
          if (opcode & 0x40)
            operand=(int) ReadBlobLSBShort(image);
          x+=operand;
          break;
        }
        case ByteDataOp:
        {
          operand=ReadBlobByte(image);
          if (opcode & 0x40)
            operand=(int) ReadBlobLSBShort(image);
          offset=((image->rows-y-1)*image->columns*number_planes)+x*
            number_planes+plane;
          operand++;
          if (offset+((size_t) operand*number_planes) > pixel_info_length)
            {
              if (number_colormaps != 0)
                colormap=(unsigned char *) RelinquishMagickMemory(colormap);
              pixel_info=RelinquishVirtualMemory(pixel_info);
              ThrowReaderException(CorruptImageError,"UnableToReadImageData");
            }
          p=pixels+offset;
          for (i=0; i < (ssize_t) operand; i++)
          {
            pixel=(unsigned char) ReadBlobByte(image);
            if ((y < (ssize_t) image->rows) &&
                ((x+i) < (ssize_t) image->columns))
              *p=pixel;
            p+=number_planes;
          }
          if (operand & 0x01)
            (void) ReadBlobByte(image);
          x+=operand;
          break;
        }
        case RunDataOp:
        {
          operand=ReadBlobByte(image);
          if (opcode & 0x40)
            operand=(int) ReadBlobLSBShort(image);
          pixel=(unsigned char) ReadBlobByte(image);
          (void) ReadBlobByte(image);
          offset=((image->rows-y-1)*image->columns*number_planes)+x*
            number_planes+plane;
          operand++;
          if (offset+((size_t) operand*number_planes) > pixel_info_length)
            {
              if (number_colormaps != 0)
                colormap=(unsigned char *) RelinquishMagickMemory(colormap);
              pixel_info=RelinquishVirtualMemory(pixel_info);
              ThrowReaderException(CorruptImageError,"UnableToReadImageData");
            }
          p=pixels+offset;
          for (i=0; i < (ssize_t) operand; i++)
          {
            if ((y < (ssize_t) image->rows) &&
                ((x+i) < (ssize_t) image->columns))
              *p=pixel;
            p+=number_planes;
          }
          x+=operand;
          break;
        }
        default:
          break;
      }
      opcode=ReadBlobByte(image);
    } while (((opcode & 0x3f) != EOFOp) && (opcode != EOF));
    if (number_colormaps != 0)
      {
        MagickStatusType
          mask;

        /*
          Apply colormap affineation to image.
        */
        mask=(MagickStatusType) (map_length-1);
        p=pixels;
        x=(ssize_t) number_planes;
        if (number_colormaps == 1)
          for (i=0; i < (ssize_t) number_pixels; i++)
          {
            if (IsValidColormapIndex(image,*p & mask,&index,exception) ==
                MagickFalse)
              break;
            *p=colormap[(ssize_t) index];
            p++;
          }
        else
          if ((number_planes >= 3) && (number_colormaps >= 3))
            for (i=0; i < (ssize_t) number_pixels; i++)
              for (x=0; x < (ssize_t) number_planes; x++)
              {
                if (IsValidColormapIndex(image,(size_t) (x*map_length+
                    (*p & mask)),&index,exception) == MagickFalse)
                  break;
                *p=colormap[(ssize_t) index];
                p++;
              }
        if ((i < (ssize_t) number_pixels) || (x < (ssize_t) number_planes))
          {
            colormap=(unsigned char *) RelinquishMagickMemory(colormap);
            pixel_info=RelinquishVirtualMemory(pixel_info);
            ThrowReaderException(CorruptImageError,"UnableToReadImageData");
          }
      }
    /*
      Initialize image structure.
    */
    if (number_planes >= 3)
      {
        /*
          Convert raster image to DirectClass pixel packets.
        */
        p=pixels;
        for (y=0; y < (ssize_t) image->rows; y++)
        {
          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
          if (q == (Quantum *) NULL)
            break;
          for (x=0; x < (ssize_t) image->columns; x++)
          {
            SetPixelRed(image,ScaleCharToQuantum(*p++),q);
            SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
            SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
            if (image->alpha_trait != UndefinedPixelTrait)
              SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
            q+=GetPixelChannels(image);
          }
          if (SyncAuthenticPixels(image,exception) == MagickFalse)
            break;
          if (image->previous == (Image *) NULL)
            {
              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                image->rows);
              if (status == MagickFalse)
                break;
            }
        }
      }
    else
      {
        /*
          Create colormap.
        */
        if (number_colormaps == 0)
          map_length=256;
        if (AcquireImageColormap(image,map_length,exception) == MagickFalse)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        p=colormap;
        if (number_colormaps == 1)
          for (i=0; i < (ssize_t) image->colors; i++)
          {
            /*
              Pseudocolor.
            */
            image->colormap[i].red=(MagickRealType)
              ScaleCharToQuantum((unsigned char) i);
            image->colormap[i].green=(MagickRealType)
              ScaleCharToQuantum((unsigned char) i);
            image->colormap[i].blue=(MagickRealType)
              ScaleCharToQuantum((unsigned char) i);
          }
        else
          if (number_colormaps > 1)
            for (i=0; i < (ssize_t) image->colors; i++)
            {
              image->colormap[i].red=(MagickRealType)
                ScaleCharToQuantum(*p);
              image->colormap[i].green=(MagickRealType)
                ScaleCharToQuantum(*(p+map_length));
              image->colormap[i].blue=(MagickRealType)
                ScaleCharToQuantum(*(p+map_length*2));
              p++;
            }
        p=pixels;
        if (image->alpha_trait == UndefinedPixelTrait)
          {
            /*
              Convert raster image to PseudoClass pixel packets.
            */
            for (y=0; y < (ssize_t) image->rows; y++)
            {
              q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
              if (q == (Quantum *) NULL)
                break;
              for (x=0; x < (ssize_t) image->columns; x++)
              {
                SetPixelIndex(image,*p++,q);
                q+=GetPixelChannels(image);
              }
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
                break;
              if (image->previous == (Image *) NULL)
                {
                  status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
                    y,image->rows);
                  if (status == MagickFalse)
                    break;
                }
            }
            (void) SyncImage(image,exception);
          }
        else
          {
            /*
              Image has a matte channel-- promote to DirectClass.
            */
            for (y=0; y < (ssize_t) image->rows; y++)
            {
              q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
              if (q == (Quantum *) NULL)
                break;
              for (x=0; x < (ssize_t) image->columns; x++)
              {
                if (IsValidColormapIndex(image,(ssize_t) *p++,&index,
                    exception) == MagickFalse)
                  break;
                SetPixelRed(image,ClampToQuantum(image->colormap[(ssize_t)
                  index].red),q);
                if (IsValidColormapIndex(image,(ssize_t) *p++,&index,
                    exception) == MagickFalse)
                  break;
                SetPixelGreen(image,ClampToQuantum(image->colormap[(ssize_t)
                  index].green),q);
                if (IsValidColormapIndex(image,(ssize_t) *p++,&index,
                    exception) == MagickFalse)
                  break;
                SetPixelBlue(image,ClampToQuantum(image->colormap[(ssize_t)
                  index].blue),q);
                SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
                q+=GetPixelChannels(image);
              }
              if (x < (ssize_t) image->columns)
                break;
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
                break;
              if (image->previous == (Image *) NULL)
                {
                  status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
                    y,image->rows);
                  if (status == MagickFalse)
                    break;
                }
            }
            image->colormap=(PixelInfo *) RelinquishMagickMemory(
              image->colormap);
            image->storage_class=DirectClass;
            image->colors=0;
          }
      }
    if (number_colormaps != 0)
      colormap=(unsigned char *) RelinquishMagickMemory(colormap);
    pixel_info=RelinquishVirtualMemory(pixel_info);
    if (EOFBlob(image) != MagickFalse)
      {
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
          image->filename);
        break;
      }
    /*
      Proceed to next image.
    */
    if (image_info->number_scenes != 0)
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    (void) ReadBlobByte(image);
    count=ReadBlob(image,2,(unsigned char *) magick);
    if ((count != 0) && (memcmp(magick,"\122\314",2) == 0))
      {
        /*
          Allocate next image structure.
        */
        AcquireNextImage(image_info,image,exception);
        if (GetNextImageInList(image) == (Image *) NULL)
          {
            image=DestroyImageList(image);
            return((Image *) NULL);
          }
        image=SyncNextImageInList(image);
        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
          GetBlobSize(image));
        if (status == MagickFalse)
          break;
      }
  } while ((count != 0) && (memcmp(magick,"\122\314",2) == 0));
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}
示例#21
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   G e t I m a g e D e p t h                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  GetImageDepth() returns the depth of a particular image channel.
%
%  The format of the GetImageDepth method is:
%
%      size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
{
  CacheView
    *image_view;

  MagickBooleanType
    status;

  register ssize_t
    id;

  size_t
    *current_depth,
    depth,
    number_threads;

  ssize_t
    y;

  /*
    Compute image depth.
  */
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
  current_depth=(size_t *) AcquireQuantumMemory(number_threads,
    sizeof(*current_depth));
  if (current_depth == (size_t *) NULL)
    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
  status=MagickTrue;
  for (id=0; id < (ssize_t) number_threads; id++)
    current_depth[id]=1;
  if ((image->storage_class == PseudoClass) && (image->alpha_trait != BlendPixelTrait))
    {
      register ssize_t
        i;

#if defined(MAGICKCORE_OPENMP_SUPPORT)
      #pragma omp parallel for schedule(static,4) shared(status) \
        if ((image->colors) > 256) \
          num_threads(GetMagickResourceLimit(ThreadResource))
#endif
      for (i=0; i < (ssize_t) image->colors; i++)
      {
        const int
          id = GetOpenMPThreadId();

        if (status == MagickFalse)
          continue;
        while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
        {
          MagickStatusType
            status;

          QuantumAny
            range;

          status=0;
          range=GetQuantumRange(current_depth[id]);
          if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
            status|=ClampToQuantum(image->colormap[i].red) !=
              ScaleAnyToQuantum(ScaleQuantumToAny(ClampToQuantum(
              image->colormap[i].red),range),range);
          if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
            status|=ClampToQuantum(image->colormap[i].green) !=
              ScaleAnyToQuantum(ScaleQuantumToAny(ClampToQuantum(
              image->colormap[i].green),range),range);
          if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
            status|=ClampToQuantum(image->colormap[i].blue) !=
              ScaleAnyToQuantum(ScaleQuantumToAny(ClampToQuantum(
              image->colormap[i].blue),range),range);
          if (status == 0)
            break;
          current_depth[id]++;
        }
      }
      depth=current_depth[0];
      for (id=1; id < (ssize_t) number_threads; id++)
        if (depth < current_depth[id])
          depth=current_depth[id];
      current_depth=(size_t *) RelinquishMagickMemory(current_depth);
      return(depth);
    }
  image_view=AcquireVirtualCacheView(image,exception);
#if !defined(MAGICKCORE_HDRI_SUPPORT)
  if (QuantumRange <= MaxMap)
    {
      register ssize_t
        i;

      size_t
        *depth_map;

      /*
        Scale pixels to desired (optimized with depth map).
      */
      depth_map=(size_t *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map));
      if (depth_map == (size_t *) NULL)
        ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
      for (i=0; i <= (ssize_t) MaxMap; i++)
      {
        unsigned int
          depth;

        for (depth=1; depth < MAGICKCORE_QUANTUM_DEPTH; depth++)
        {
          Quantum
            pixel;

          QuantumAny
            range;

          range=GetQuantumRange(depth);
          pixel=(Quantum) i;
          if (pixel == ScaleAnyToQuantum(ScaleQuantumToAny(pixel,range),range))
            break;
        }
        depth_map[i]=depth;
      }
#if defined(MAGICKCORE_OPENMP_SUPPORT)
      #pragma omp parallel for schedule(static,4) shared(status) \
        magick_threads(image,image,image->rows,1)
#endif
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        const int
          id = GetOpenMPThreadId();

        register const Quantum
          *restrict p;

        register ssize_t
          x;

        if (status == MagickFalse)
          continue;
        p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
        if (p == (const Quantum *) NULL)
          continue;
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          register ssize_t
            i;

          if (GetPixelReadMask(image,p) == 0)
            {
              p+=GetPixelChannels(image);
              continue;
            }
          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
          {
            PixelChannel channel=GetPixelChannelChannel(image,i);
            PixelTrait traits=GetPixelChannelTraits(image,channel);
            if ((traits == UndefinedPixelTrait) ||
                (channel == IndexPixelChannel) ||
                (channel == ReadMaskPixelChannel) || (channel == MetaPixelChannel))
              continue;
            if (depth_map[ScaleQuantumToMap(p[i])] > current_depth[id])
              current_depth[id]=depth_map[ScaleQuantumToMap(p[i])];
          }
          p+=GetPixelChannels(image);
        }
        if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
          status=MagickFalse;
      }
      image_view=DestroyCacheView(image_view);
      depth=current_depth[0];
      for (id=1; id < (ssize_t) number_threads; id++)
        if (depth < current_depth[id])
          depth=current_depth[id];
      depth_map=(size_t *) RelinquishMagickMemory(depth_map);
      current_depth=(size_t *) RelinquishMagickMemory(current_depth);
      return(depth);
    }
#endif
  /*
    Compute pixel depth.
  */
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(static,4) shared(status) \
    magick_threads(image,image,image->rows,1)
#endif
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    const int
      id = GetOpenMPThreadId();

    register const Quantum
      *restrict p;

    register ssize_t
      x;

    if (status == MagickFalse)
      continue;
    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
    if (p == (const Quantum *) NULL)
      continue;
    for (x=0; x < (ssize_t) image->columns; x++)
    {
      register ssize_t
        i;

      if (GetPixelReadMask(image,p) == 0)
        {
          p+=GetPixelChannels(image);
          continue;
        }
      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
      {
        PixelChannel
          channel;

        PixelTrait
          traits;

        channel=GetPixelChannelChannel(image,i);
        traits=GetPixelChannelTraits(image,channel);
        if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) ||
            (channel == ReadMaskPixelChannel))
          continue;
        while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
        {
          QuantumAny
            range;

          range=GetQuantumRange(current_depth[id]);
          if (p[i] == ScaleAnyToQuantum(ScaleQuantumToAny(p[i],range),range))
            break;
          current_depth[id]++;
        }
      }
      p+=GetPixelChannels(image);
    }
    if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
      status=MagickFalse;
  }
  image_view=DestroyCacheView(image_view);
  depth=current_depth[0];
  for (id=1; id < (ssize_t) number_threads; id++)
    if (depth < current_depth[id])
      depth=current_depth[id];
  current_depth=(size_t *) RelinquishMagickMemory(current_depth);
  return(depth);
}
示例#22
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   F l o o d f i l l P a i n t I m a g e                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  FloodfillPaintImage() changes the color value of any pixel that matches
%  target and is an immediate neighbor.  If the method FillToBorderMethod is
%  specified, the color value is changed for any neighbor pixel that does not
%  match the bordercolor member of image.
%
%  By default target must match a particular pixel color exactly.
%  However, in many cases two colors may differ by a small amount.  The
%  fuzz member of image defines how much tolerance is acceptable to
%  consider two colors as the same.  For example, set fuzz to 10 and the
%  color red at intensities of 100 and 102 respectively are now
%  interpreted as the same color for the purposes of the floodfill.
%
%  The format of the FloodfillPaintImage method is:
%
%      MagickBooleanType FloodfillPaintImage(Image *image,
%        const ChannelType channel,const DrawInfo *draw_info,
%        const MagickPixelPacket target,const ssize_t x_offset,
%        const ssize_t y_offset,const MagickBooleanType invert)
%
%  A description of each parameter follows:
%
%    o image: the image.
%
%    o channel: the channel(s).
%
%    o draw_info: the draw info.
%
%    o target: the RGB value of the target color.
%
%    o x_offset,y_offset: the starting location of the operation.
%
%    o invert: paint any pixel that does not match the target color.
%
*/
MagickExport MagickBooleanType FloodfillPaintImage(Image *image,
  const ChannelType channel,const DrawInfo *draw_info,
  const MagickPixelPacket *target,const ssize_t x_offset,const ssize_t y_offset,
  const MagickBooleanType invert)
{
#define MaxStacksize  (1UL << 15)
#define PushSegmentStack(up,left,right,delta) \
{ \
  if (s >= (segment_stack+MaxStacksize)) \
    ThrowBinaryException(DrawError,"SegmentStackOverflow",image->filename) \
  else \
    { \
      if ((((up)+(delta)) >= 0) && (((up)+(delta)) < (ssize_t) image->rows)) \
        { \
          s->x1=(double) (left); \
          s->y1=(double) (up); \
          s->x2=(double) (right); \
          s->y2=(double) (delta); \
          s++; \
        } \
    } \
}

  CacheView
    *floodplane_view,
    *image_view;

  ExceptionInfo
    *exception;

  Image
    *floodplane_image;

  MagickBooleanType
    skip;

  MagickPixelPacket
    fill,
    pixel;

  PixelPacket
    fill_color;

  register SegmentInfo
    *s;

  SegmentInfo
    *segment_stack;

  ssize_t
    offset,
    start,
    x,
    x1,
    x2,
    y;

  /*
    Check boundary conditions.
  */
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(draw_info != (DrawInfo *) NULL);
  assert(draw_info->signature == MagickSignature);
  if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns))
    return(MagickFalse);
  if ((y_offset < 0) || (y_offset >= (ssize_t) image->rows))
    return(MagickFalse);
  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
    return(MagickFalse);
  if (IsGrayColorspace(image->colorspace) != MagickFalse)
    (void) TransformImageColorspace(image,sRGBColorspace);
  if ((image->matte == MagickFalse) &&
      (draw_info->fill.opacity != OpaqueOpacity))
    (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
  /*
    Set floodfill state.
  */
  floodplane_image=CloneImage(image,0,0,MagickTrue,&image->exception);
  if (floodplane_image == (Image *) NULL)
    return(MagickFalse);
  (void) SetImageAlphaChannel(floodplane_image,OpaqueAlphaChannel);
  segment_stack=(SegmentInfo *) AcquireQuantumMemory(MaxStacksize,
    sizeof(*segment_stack));
  if (segment_stack == (SegmentInfo *) NULL)
    {
      floodplane_image=DestroyImage(floodplane_image);
      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
        image->filename);
    }
  /*
    Push initial segment on stack.
  */
  exception=(&image->exception);
  x=x_offset;
  y=y_offset;
  start=0;
  s=segment_stack;
  PushSegmentStack(y,x,x,1);
  PushSegmentStack(y+1,x,x,-1);
  GetMagickPixelPacket(image,&fill);
  GetMagickPixelPacket(image,&pixel);
  image_view=AcquireVirtualCacheView(image,exception);
  floodplane_view=AcquireAuthenticCacheView(floodplane_image,exception);
  while (s > segment_stack)
  {
    register const IndexPacket
      *restrict indexes;

    register const PixelPacket
      *restrict p;

    register ssize_t
      x;

    register PixelPacket
      *restrict q;

    /*
      Pop segment off stack.
    */
    s--;
    x1=(ssize_t) s->x1;
    x2=(ssize_t) s->x2;
    offset=(ssize_t) s->y2;
    y=(ssize_t) s->y1+offset;
    /*
      Recolor neighboring pixels.
    */
    p=GetCacheViewVirtualPixels(image_view,0,y,(size_t) (x1+1),1,exception);
    q=GetCacheViewAuthenticPixels(floodplane_view,0,y,(size_t) (x1+1),1,
      exception);
    if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
      break;
    indexes=GetCacheViewVirtualIndexQueue(image_view);
    p+=x1;
    q+=x1;
    for (x=x1; x >= 0; x--)
    {
      if (q->opacity == (Quantum) TransparentOpacity)
        break;
      SetMagickPixelPacket(image,p,indexes+x,&pixel);
      if (IsMagickColorSimilar(&pixel,target) == invert)
        break;
      q->opacity=(Quantum) TransparentOpacity;
      p--;
      q--;
    }
    if (SyncCacheViewAuthenticPixels(floodplane_view,exception) == MagickFalse)
      break;
    skip=x >= x1 ? MagickTrue : MagickFalse;
    if (skip == MagickFalse)
      {
        start=x+1;
        if (start < x1)
          PushSegmentStack(y,start,x1-1,-offset);
        x=x1+1;
      }
    do
    {
      if (skip == MagickFalse)
        {
          if (x < (ssize_t) image->columns)
            {
              p=GetCacheViewVirtualPixels(image_view,x,y,image->columns-x,1,
                exception);
              q=GetCacheViewAuthenticPixels(floodplane_view,x,y,
                image->columns-x,1,exception);
              if ((p == (const PixelPacket *) NULL) ||
                  (q == (PixelPacket *) NULL))
                break;
              indexes=GetCacheViewVirtualIndexQueue(image_view);
              for ( ; x < (ssize_t) image->columns; x++)
              {
                if (q->opacity == (Quantum) TransparentOpacity)
                  break;
                SetMagickPixelPacket(image,p,indexes+x,&pixel);
                if (IsMagickColorSimilar(&pixel,target) == invert)
                  break;
                q->opacity=(Quantum) TransparentOpacity;
                p++;
                q++;
              }
              if (SyncCacheViewAuthenticPixels(floodplane_view,exception) == MagickFalse)
                break;
            }
          PushSegmentStack(y,start,x-1,offset);
          if (x > (x2+1))
            PushSegmentStack(y,x2+1,x-1,-offset);
        }
      skip=MagickFalse;
      x++;
      if (x <= x2)
        {
          p=GetCacheViewVirtualPixels(image_view,x,y,(size_t) (x2-x+1),1,
            exception);
          q=GetCacheViewAuthenticPixels(floodplane_view,x,y,(size_t) (x2-x+1),1,
            exception);
          if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
            break;
          indexes=GetCacheViewVirtualIndexQueue(image_view);
          for ( ; x <= x2; x++)
          {
            if (q->opacity == (Quantum) TransparentOpacity)
              break;
            SetMagickPixelPacket(image,p,indexes+x,&pixel);
            if (IsMagickColorSimilar(&pixel,target) != invert)
              break;
            p++;
            q++;
          }
        }
      start=x;
    } while (x <= x2);
  }
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    register const PixelPacket
      *restrict p;

    register IndexPacket
      *restrict indexes;

    register ssize_t
      x;

    register PixelPacket
      *restrict q;

    /*
      Tile fill color onto floodplane.
    */
    p=GetCacheViewVirtualPixels(floodplane_view,0,y,image->columns,1,
      exception);
    q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
    if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
      break;
    indexes=GetCacheViewAuthenticIndexQueue(image_view);
    for (x=0; x < (ssize_t) image->columns; x++)
    {
      if (GetPixelOpacity(p) != OpaqueOpacity)
        {
          (void) GetFillColor(draw_info,x,y,&fill_color);
          SetMagickPixelPacket(image,&fill_color,(IndexPacket *) NULL,&fill);
          if (image->colorspace == CMYKColorspace)
            ConvertRGBToCMYK(&fill);
          if ((channel & RedChannel) != 0)
            SetPixelRed(q,ClampToQuantum(fill.red));
          if ((channel & GreenChannel) != 0)
            SetPixelGreen(q,ClampToQuantum(fill.green));
          if ((channel & BlueChannel) != 0)
            SetPixelBlue(q,ClampToQuantum(fill.blue));
          if ((channel & OpacityChannel) != 0)
            SetPixelOpacity(q,ClampToQuantum(fill.opacity));
          if (((channel & IndexChannel) != 0) &&
              (image->colorspace == CMYKColorspace))
            SetPixelIndex(indexes+x,ClampToQuantum(fill.index));
        }
      p++;
      q++;
    }
    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
      break;
  }
  floodplane_view=DestroyCacheView(floodplane_view);
  image_view=DestroyCacheView(image_view);
  segment_stack=(SegmentInfo *) RelinquishMagickMemory(segment_stack);
  floodplane_image=DestroyImage(floodplane_image);
  return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
}
示例#23
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   S e t I m a g e D e p t h                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  SetImageDepth() sets the depth of the image.
%
%  The format of the SetImageDepth method is:
%
%      MagickBooleanType SetImageDepth(Image *image,const size_t depth,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image: the image.
%
%    o channel: the channel.
%
%    o depth: the image depth.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType SetImageDepth(Image *image,
  const size_t depth,ExceptionInfo *exception)
{
  CacheView
    *image_view;

  MagickBooleanType
    status;

  QuantumAny
    range;

  ssize_t
    y;

  assert(image != (Image *) NULL);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  assert(image->signature == MagickSignature);
  if (depth >= MAGICKCORE_QUANTUM_DEPTH)
    {
      image->depth=depth;
      return(MagickTrue);
    }
  range=GetQuantumRange(depth);
  if (image->storage_class == PseudoClass)
    {
      register ssize_t
        i;

#if defined(MAGICKCORE_OPENMP_SUPPORT)
      #pragma omp parallel for schedule(static,4) shared(status) \
        magick_threads(image,image,1,1)
#endif
      for (i=0; i < (ssize_t) image->colors; i++)
      {
        if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
          image->colormap[i].red=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
            ClampToQuantum(image->colormap[i].red),range),range);
        if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
          image->colormap[i].green=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
            ClampToQuantum(image->colormap[i].green),range),range);
        if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
          image->colormap[i].blue=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
            ClampToQuantum(image->colormap[i].blue),range),range);
        if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
          image->colormap[i].alpha=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
            ClampToQuantum(image->colormap[i].alpha),range),range);
      }
    }
  status=MagickTrue;
  image_view=AcquireAuthenticCacheView(image,exception);
#if !defined(MAGICKCORE_HDRI_SUPPORT)
  if (QuantumRange <= MaxMap)
    {
      Quantum
        *depth_map;

      register ssize_t
        i;

      /*
        Scale pixels to desired (optimized with depth map).
      */
      depth_map=(Quantum *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map));
      if (depth_map == (Quantum *) NULL)
        ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
      for (i=0; i <= (ssize_t) MaxMap; i++)
        depth_map[i]=ScaleAnyToQuantum(ScaleQuantumToAny((Quantum) i,range),
          range);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
      #pragma omp parallel for schedule(static,4) shared(status) \
        magick_threads(image,image,image->rows,1)
#endif
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        register ssize_t
          x;

        register Quantum
          *restrict q;

        if (status == MagickFalse)
          continue;
        q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
          exception);
        if (q == (Quantum *) NULL)
          {
            status=MagickFalse;
            continue;
          }
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          register ssize_t
            i;

          if (GetPixelReadMask(image,q) == 0)
            {
              q+=GetPixelChannels(image);
              continue;
            }
          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
          {
            PixelChannel
              channel;

            PixelTrait
              traits;

            channel=GetPixelChannelChannel(image,i);
            traits=GetPixelChannelTraits(image,channel);
            if ((traits == UndefinedPixelTrait) ||
                (channel == IndexPixelChannel) || (channel == ReadMaskPixelChannel))
              continue;
            q[i]=depth_map[ScaleQuantumToMap(q[i])];
          }
          q+=GetPixelChannels(image);
        }
        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
          {
            status=MagickFalse;
            continue;
          }
      }
      image_view=DestroyCacheView(image_view);
      depth_map=(Quantum *) RelinquishMagickMemory(depth_map);
      if (status != MagickFalse)
        image->depth=depth;
      return(status);
    }
示例#24
0
static Image *ReadFITSImage(const ImageInfo *image_info,
                            ExceptionInfo *exception)
{
    typedef struct _FITSInfo
    {
        MagickBooleanType
        extend,
        simple;

        int
        bits_per_pixel,
        columns,
        rows,
        number_axes,
        number_planes;

        double
        min_data,
        max_data,
        zero,
        scale;

        EndianType
        endian;
    } FITSInfo;

    char
    *comment,
    keyword[9],
    property[MaxTextExtent],
    value[73];

    double
    pixel,
    scale;

    FITSInfo
    fits_info;

    Image
    *image;

    int
    c;

    MagickBooleanType
    status;

    MagickSizeType
    number_pixels;

    register ssize_t
    i,
    x;

    register PixelPacket
    *q;

    ssize_t
    count,
    scene,
    y;

    /*
      Open image file.
    */
    assert(image_info != (const ImageInfo *) NULL);
    assert(image_info->signature == MagickSignature);
    if (image_info->debug != MagickFalse)
        (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
                              image_info->filename);
    assert(exception != (ExceptionInfo *) NULL);
    assert(exception->signature == MagickSignature);
    image=AcquireImage(image_info);
    status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    if (status == MagickFalse)
    {
        image=DestroyImageList(image);
        return((Image *) NULL);
    }
    /*
      Initialize image header.
    */
    (void) ResetMagickMemory(&fits_info,0,sizeof(fits_info));
    fits_info.extend=MagickFalse;
    fits_info.simple=MagickFalse;
    fits_info.bits_per_pixel=8;
    fits_info.columns=1;
    fits_info.rows=1;
    fits_info.rows=1;
    fits_info.number_planes=1;
    fits_info.min_data=0.0;
    fits_info.max_data=0.0;
    fits_info.zero=0.0;
    fits_info.scale=1.0;
    fits_info.endian=MSBEndian;
    /*
      Decode image header.
    */
    for (comment=(char *) NULL; EOFBlob(image) == MagickFalse; )
    {
        for ( ; EOFBlob(image) == MagickFalse; )
        {
            register char
            *p;

            count=ReadBlob(image,8,(unsigned char *) keyword);
            if (count != 8)
                break;
            for (i=0; i < 8; i++)
            {
                if (isspace((int) ((unsigned char) keyword[i])) != 0)
                    break;
                keyword[i]=tolower((int) ((unsigned char) keyword[i]));
            }
            keyword[i]='\0';
            count=ReadBlob(image,72,(unsigned char *) value);
            if (count != 72)
                break;
            value[72]='\0';
            p=value;
            if (*p == '=')
            {
                p+=2;
                while (isspace((int) ((unsigned char) *p)) != 0)
                    p++;
            }
            if (LocaleCompare(keyword,"end") == 0)
                break;
            if (LocaleCompare(keyword,"extend") == 0)
                fits_info.extend=(*p == 'T') || (*p == 't') ? MagickTrue : MagickFalse;
            if (LocaleCompare(keyword,"simple") == 0)
                fits_info.simple=(*p == 'T') || (*p == 't') ? MagickTrue : MagickFalse;
            if (LocaleCompare(keyword,"bitpix") == 0)
                fits_info.bits_per_pixel=StringToLong(p);
            if (LocaleCompare(keyword,"naxis") == 0)
                fits_info.number_axes=StringToLong(p);
            if (LocaleCompare(keyword,"naxis1") == 0)
                fits_info.columns=StringToLong(p);
            if (LocaleCompare(keyword,"naxis2") == 0)
                fits_info.rows=StringToLong(p);
            if (LocaleCompare(keyword,"naxis3") == 0)
                fits_info.number_planes=StringToLong(p);
            if (LocaleCompare(keyword,"datamax") == 0)
                fits_info.max_data=InterpretLocaleValue(p,(char **) NULL);
            if (LocaleCompare(keyword,"datamin") == 0)
                fits_info.min_data=InterpretLocaleValue(p,(char **) NULL);
            if (LocaleCompare(keyword,"bzero") == 0)
                fits_info.zero=InterpretLocaleValue(p,(char **) NULL);
            if (LocaleCompare(keyword,"bscale") == 0)
                fits_info.scale=InterpretLocaleValue(p,(char **) NULL);
            if (LocaleCompare(keyword,"comment") == 0)
            {
                if (comment == (char *) NULL)
                    comment=ConstantString(p);
                else
                    (void) ConcatenateString(&comment,p);
            }
            if (LocaleCompare(keyword,"xendian") == 0)
            {
                if (LocaleNCompare(p,"big",3) == 0)
                    fits_info.endian=MSBEndian;
                else
                    fits_info.endian=LSBEndian;
            }
            (void) FormatLocaleString(property,MaxTextExtent,"fits:%s",keyword);
            (void) SetImageProperty(image,property,p);
        }
        c=0;
        while (((TellBlob(image) % FITSBlocksize) != 0) && (c != EOF))
            c=ReadBlobByte(image);
        if (fits_info.extend == MagickFalse)
            break;
        number_pixels=(MagickSizeType) fits_info.columns*fits_info.rows;
        if ((fits_info.simple != MagickFalse) && (fits_info.number_axes >= 1) &&
                (fits_info.number_axes <= 4) && (number_pixels != 0))
            break;
    }
    /*
      Verify that required image information is defined.
    */
    if (comment != (char *) NULL)
    {
        (void) SetImageProperty(image,"comment",comment);
        comment=DestroyString(comment);
    }
    if (EOFBlob(image) != MagickFalse)
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
                           image->filename);
    number_pixels=(MagickSizeType) fits_info.columns*fits_info.rows;
    if ((fits_info.simple == MagickFalse) || (fits_info.number_axes < 1) ||
            (fits_info.number_axes > 4) || (number_pixels == 0))
        ThrowReaderException(CorruptImageError,"ImageTypeNotSupported");
    for (scene=0; scene < (ssize_t) fits_info.number_planes; scene++)
    {
        image->columns=(size_t) fits_info.columns;
        image->rows=(size_t) fits_info.rows;
        image->depth=(size_t) (fits_info.bits_per_pixel < 0 ? -1 : 1)*
                     fits_info.bits_per_pixel;
        image->endian=fits_info.endian;
        image->scene=(size_t) scene;
        if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
            if (image->scene >= (image_info->scene+image_info->number_scenes-1))
                break;
        /*
          Initialize image structure.
        */
        if ((fits_info.min_data != 0.0) || (fits_info.max_data != 0.0))
        {
            if ((fits_info.bits_per_pixel != 0) && (fits_info.max_data == 0.0))
                fits_info.max_data=GetFITSPixelRange((size_t)
                                                     fits_info.bits_per_pixel);
        }
        else
            GetFITSPixelExtrema(image,fits_info.bits_per_pixel,&fits_info.min_data,
                                &fits_info.max_data);
        /*
          Convert FITS pixels to pixel packets.
        */
        scale=(double) QuantumRange/(fits_info.scale*(fits_info.max_data-
                                     fits_info.min_data)+fits_info.zero);
        for (y=(ssize_t) image->rows-1; y >= 0; y--)
        {
            q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
            if (q == (PixelPacket *) NULL)
                break;
            for (x=0; x < (ssize_t) image->columns; x++)
            {
                pixel=GetFITSPixel(image,fits_info.bits_per_pixel);
                SetPixelRed(q,ClampToQuantum(scale*(fits_info.scale*(pixel-
                                                    fits_info.min_data)+fits_info.zero)));
                SetPixelGreen(q,GetPixelRed(q));
                SetPixelBlue(q,GetPixelRed(q));
                q++;
            }
            if (SyncAuthenticPixels(image,exception) == MagickFalse)
                break;
            if (image->previous == (Image *) NULL)
            {
                status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                                        image->rows);
                if (status == MagickFalse)
                    break;
            }
        }
        if (EOFBlob(image) != MagickFalse)
        {
            ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
                               image->filename);
            break;
        }
        /*
          Proceed to next image.
        */
        if (image_info->number_scenes != 0)
            if (image->scene >= (image_info->scene+image_info->number_scenes-1))
                break;
        if (scene < (ssize_t) (fits_info.number_planes-1))
        {
            /*
              Allocate next image structure.
            */
            AcquireNextImage(image_info,image);
            if (GetNextImageInList(image) == (Image *) NULL)
            {
                image=DestroyImageList(image);
                return((Image *) NULL);
            }
            image=SyncNextImageInList(image);
            status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
                                    GetBlobSize(image));
            if (status == MagickFalse)
                break;
        }
    }
    (void) CloseBlob(image);
    return(GetFirstImageInList(image));
}
示例#25
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   S e t I m a g e A l p h a C h a n n e l                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  SetImageAlphaChannel() activates, deactivates, resets, or sets the alpha
%  channel.
%
%  The format of the SetImageAlphaChannel method is:
%
%      MagickBooleanType SetImageAlphaChannel(Image *image,
%        const AlphaChannelType alpha_type)
%
%  A description of each parameter follows:
%
%    o image: the image.
%
%    o alpha_type:  The alpha channel type: ActivateAlphaChannel,
%      CopyAlphaChannel, DeactivateAlphaChannel, ExtractAlphaChannel,
%      OpaqueAlphaChannel, ResetAlphaChannel, SetAlphaChannel,
%      ShapeAlphaChannel, and TransparentAlphaChannel.
%
*/
MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
  const AlphaChannelType alpha_type)
{
  MagickBooleanType
    status;

  assert(image != (Image *) NULL);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  assert(image->signature == MagickSignature);
  status=MagickTrue;
  switch (alpha_type)
  {
    case ActivateAlphaChannel:
    {
      image->matte=MagickTrue;
      break;
    }
    case BackgroundAlphaChannel:
    {
      CacheView
        *image_view;

      ExceptionInfo
        *exception;

      IndexPacket
        index;

      MagickBooleanType
        status;

      MagickPixelPacket
        background;

      PixelPacket
        pixel;

      ssize_t
        y;

      /*
        Set transparent pixels to background color.
      */
      if (image->matte == MagickFalse)
        break;
      if (SetImageStorageClass(image,DirectClass) == MagickFalse)
        break;
      GetMagickPixelPacket(image,&background);
      SetMagickPixelPacket(image,&image->background_color,(const IndexPacket *)
        NULL,&background);
      if (image->colorspace == CMYKColorspace)
        ConvertRGBToCMYK(&background);
      index=0;
      SetPixelPacket(image,&background,&pixel,&index);
      status=MagickTrue;
      exception=(&image->exception);
      image_view=AcquireAuthenticCacheView(image,exception);
      #if defined(MAGICKCORE_OPENMP_SUPPORT)
        #pragma omp parallel for schedule(static,4) shared(status) \
          magick_threads(image,image,image->rows,1)
      #endif
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        register IndexPacket
          *restrict indexes;

        register PixelPacket
          *restrict q;

        register ssize_t
          x;

        if (status == MagickFalse)
          continue;
        q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
          exception);
        if (q == (PixelPacket *) NULL)
          {
            status=MagickFalse;
            continue;
          }
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          if (q->opacity == TransparentOpacity)
            {
              SetPixelRed(q,pixel.red);
              SetPixelGreen(q,pixel.green);
              SetPixelBlue(q,pixel.blue);
            }
          q++;
        }
        if (image->colorspace == CMYKColorspace)
          {
            indexes=GetCacheViewAuthenticIndexQueue(image_view);
            for (x=0; x < (ssize_t) image->columns; x++)
              SetPixelIndex(indexes+x,index);
          }
        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
          status=MagickFalse;
      }
      image_view=DestroyCacheView(image_view);
      return(status);
    }
    case CopyAlphaChannel:
    case ShapeAlphaChannel:
    {
      /*
        Special usage case for SeparateImageChannel(): copy grayscale color to
        the alpha channel.
      */
      status=SeparateImageChannel(image,GrayChannels);
      image->matte=MagickTrue; /* make sure transparency is now on! */
      if (alpha_type == ShapeAlphaChannel)
        {
          MagickPixelPacket
            background;

          /*
            Reset all color channels to background color.
          */
          GetMagickPixelPacket(image,&background);
          SetMagickPixelPacket(image,&(image->background_color),(IndexPacket *)
            NULL,&background);
          (void) LevelColorsImage(image,&background,&background,MagickTrue);
        }
      break;
    }
    case DeactivateAlphaChannel:
    {
      image->matte=MagickFalse;
      break;
    }
    case ExtractAlphaChannel:
    {
      status=SeparateImageChannel(image,TrueAlphaChannel);
      image->matte=MagickFalse;
      break;
    }
    case RemoveAlphaChannel:
    case FlattenAlphaChannel:
    {
      CacheView
        *image_view;

      ExceptionInfo
        *exception;

      IndexPacket
        index;

      MagickBooleanType
        status;

      MagickPixelPacket
        background;

      PixelPacket
        pixel;

      ssize_t
        y;

      /*
        Flatten image pixels over the background pixels.
      */
      if (image->matte == MagickFalse)
        break;
      if (SetImageStorageClass(image,DirectClass) == MagickFalse)
        break;
      GetMagickPixelPacket(image,&background);
      SetMagickPixelPacket(image,&image->background_color,(const IndexPacket *)
        NULL,&background);
      if (image->colorspace == CMYKColorspace)
        ConvertRGBToCMYK(&background);
      index=0;
      SetPixelPacket(image,&background,&pixel,&index);
      status=MagickTrue;
      exception=(&image->exception);
      image_view=AcquireAuthenticCacheView(image,exception);
      #if defined(MAGICKCORE_OPENMP_SUPPORT)
        #pragma omp parallel for schedule(static,4) shared(status) \
          magick_threads(image,image,image->rows,1)
      #endif
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        register IndexPacket
          *restrict indexes;

        register PixelPacket
          *restrict q;

        register ssize_t
          x;

        if (status == MagickFalse)
          continue;
        q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
          exception);
        if (q == (PixelPacket *) NULL)
          {
            status=MagickFalse;
            continue;
          }
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          double
            gamma,
            opacity;

          gamma=1.0-QuantumScale*QuantumScale*q->opacity*pixel.opacity;
          opacity=(double) QuantumRange*(1.0-gamma);
          gamma=PerceptibleReciprocal(gamma);
          q->red=ClampToQuantum(gamma*MagickOver_((MagickRealType) q->red,
            (MagickRealType) q->opacity,(MagickRealType) pixel.red,
            (MagickRealType) pixel.opacity));
          q->green=ClampToQuantum(gamma*MagickOver_((MagickRealType) q->green,
            (MagickRealType) q->opacity,(MagickRealType) pixel.green,
            (MagickRealType) pixel.opacity));
          q->blue=ClampToQuantum(gamma*MagickOver_((MagickRealType) q->blue,
            (MagickRealType) q->opacity,(MagickRealType) pixel.blue,
            (MagickRealType) pixel.opacity));
          q->opacity=ClampToQuantum(opacity);
          q++;
        }
        if (image->colorspace == CMYKColorspace)
          {
            indexes=GetCacheViewAuthenticIndexQueue(image_view);
            for (x=0; x < (ssize_t) image->columns; x++)
              SetPixelIndex(indexes+x,index);
          }
        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
          status=MagickFalse;
      }
      image_view=DestroyCacheView(image_view);
      return(status);
    }
    case ResetAlphaChannel: /* deprecated */
    case OpaqueAlphaChannel:
    {
      status=SetImageOpacity(image,OpaqueOpacity);
      break;
    }
    case SetAlphaChannel:
    {
      if (image->matte == MagickFalse)
        status=SetImageOpacity(image,OpaqueOpacity);
      break;
    }
    case TransparentAlphaChannel:
    {
      status=SetImageOpacity(image,TransparentOpacity);
      break;
    }
    case UndefinedAlphaChannel:
      break;
  }
  if (status == MagickFalse)
    return(status);
  return(SyncImagePixelCache(image,&image->exception));
}
示例#26
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e C I P I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Procedure WriteCIPImage() writes an image to a file in the Cisco IP phone
%  image format.
%
%  The format of the WriteCIPImage method is:
%
%      MagickBooleanType WriteCIPImage(const ImageInfo *image_info,
%        Image *image,ExceptionInfo *exception)
%
%  A description of each parameter follows.
%
%    o image_info: the image info.
%
%    o image:  The image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image,
  ExceptionInfo *exception)
{
  char
    buffer[MagickPathExtent];

  const char
    *value;

  MagickBooleanType
    status;

  register const Quantum
    *p;

  register ssize_t
    i,
    x;

  ssize_t
    y;

  unsigned char
    byte;

  /*
    Open output image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickCoreSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickCoreSignature);
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
  if (status == MagickFalse)
    return(status);
  (void) WriteBlobString(image,"<CiscoIPPhoneImage>\n");
  value=GetImageProperty(image,"label",exception);
  if (value != (const char *) NULL)
    (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n",value);
  else
    {
      char
        basename[MagickPathExtent];

      GetPathComponent(image->filename,BasePath,basename);
      (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n",
        basename);
    }
  (void) WriteBlobString(image,buffer);
  (void) FormatLocaleString(buffer,MagickPathExtent,
    "<LocationX>%.20g</LocationX>\n",(double) image->page.x);
  (void) WriteBlobString(image,buffer);
  (void) FormatLocaleString(buffer,MagickPathExtent,
    "<LocationY>%.20g</LocationY>\n",(double) image->page.y);
  (void) WriteBlobString(image,buffer);
  (void) FormatLocaleString(buffer,MagickPathExtent,"<Width>%.20g</Width>\n",
    (double) (image->columns+(image->columns % 2)));
  (void) WriteBlobString(image,buffer);
  (void) FormatLocaleString(buffer,MagickPathExtent,"<Height>%.20g</Height>\n",
    (double) image->rows);
  (void) WriteBlobString(image,buffer);
  (void) FormatLocaleString(buffer,MagickPathExtent,"<Depth>2</Depth>\n");
  (void) WriteBlobString(image,buffer);
  (void) WriteBlobString(image,"<Data>");
  (void) TransformImageColorspace(image,sRGBColorspace,exception);
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
    if (p == (const Quantum *) NULL)
      break;
    for (x=0; x < ((ssize_t) image->columns-3); x+=4)
    {
      byte=(unsigned char)
        ((((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+3))/QuantumRange) & 0x03) << 6) |
         (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+2))/QuantumRange) & 0x03) << 4) |
         (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+1))/QuantumRange) & 0x03) << 2) |
         (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+0))/QuantumRange) & 0x03) << 0));
      (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",byte);
      (void) WriteBlobString(image,buffer);
      p+=4;
    }
    if ((image->columns % 4) != 0)
      {
        i=(ssize_t) image->columns % 4;
        byte=(unsigned char)
          ((((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,3)))/QuantumRange) & 0x03) << 6) |
           (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,2)))/QuantumRange) & 0x03) << 4) |
           (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,1)))/QuantumRange) & 0x03) << 2) |
           (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,0)))/QuantumRange) & 0x03) << 0));
        (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",~byte);
        (void) WriteBlobString(image,buffer);
      }
    status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
      image->rows);
    if (status == MagickFalse)
      break;
  }
  (void) WriteBlobString(image,"</Data>\n");
  (void) WriteBlobString(image,"</CiscoIPPhoneImage>\n");
  (void) CloseBlob(image);
  return(MagickTrue);
}
示例#27
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d G R A D I E N T I m a g e                                         %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadGRADIENTImage creates a gradient image and initializes it to
%  the color range as specified by the filename.  It allocates the memory
%  necessary for the new Image structure and returns a pointer to the new
%  image.
%
%  The format of the ReadGRADIENTImage method is:
%
%      Image *ReadGRADIENTImage(const ImageInfo *image_info,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadGRADIENTImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  char
    colorname[MaxTextExtent];

  MagickBooleanType
    status;

  MagickPixelPacket
    start_pixel,
    stop_pixel;

  PixelPacket
    start_color,
    stop_color;

  Image
    *image;

  /*
    Initialize Image structure.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AcquireImage(image_info);
  if ((image->columns == 0) || (image->rows == 0))
    ThrowReaderException(OptionError,"MustSpecifyImageSize");
  (void) SetImageOpacity(image,(Quantum) TransparentOpacity);
  (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent);
  (void) CopyMagickString(colorname,image_info->filename,MaxTextExtent);
  (void) sscanf(image_info->filename,"%[^-]",colorname);
  if (QueryColorDatabase(colorname,&start_color,exception) == MagickFalse)
    {
      image=DestroyImage(image);
      return((Image *) NULL);
    }
  (void) QueryMagickColor(colorname,&start_pixel,exception);
  (void) CopyMagickString(colorname,"white",MaxTextExtent);
  if (PixelIntensityToQuantum(image,&start_color) > (Quantum) (QuantumRange/2))
    (void) CopyMagickString(colorname,"black",MaxTextExtent);
  (void) sscanf(image_info->filename,"%*[^-]-%s",colorname);
  if (QueryColorDatabase(colorname,&stop_color,exception) == MagickFalse)
    {
      image=DestroyImage(image);
      return((Image *) NULL);
    }
  (void) QueryMagickColor(colorname,&stop_pixel,exception);
  if (IssRGBColorspace(start_pixel.colorspace) != MagickFalse)
    {
      start_color.red=ClampToQuantum(QuantumRange*DecompandsRGB(QuantumScale*
        start_color.red));
      start_color.green=ClampToQuantum(QuantumRange*DecompandsRGB(QuantumScale*
        start_color.green));
      start_color.blue=ClampToQuantum(QuantumRange*DecompandsRGB(QuantumScale*
        start_color.blue));
    }
  if (IssRGBColorspace(stop_pixel.colorspace) != MagickFalse)
    {
      stop_color.red=ClampToQuantum(QuantumRange*DecompandsRGB(QuantumScale*
        stop_color.red));
      stop_color.green=ClampToQuantum(QuantumRange*DecompandsRGB(QuantumScale*
        stop_color.green));
      stop_color.blue=ClampToQuantum(QuantumRange*DecompandsRGB(QuantumScale*
        stop_color.blue));
    }
  status=GradientImage(image,LocaleCompare(image_info->magick,"GRADIENT") == 0 ?
    LinearGradient : RadialGradient,PadSpread,&start_color,&stop_color);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  (void) SetImageColorspace(image,start_pixel.colorspace);
  if ((start_pixel.matte == MagickFalse) && (stop_pixel.matte == MagickFalse))
    (void) SetImageAlphaChannel(image,DeactivateAlphaChannel);
  if (IssRGBColorspace(start_pixel.colorspace) != MagickFalse)
    {
      (void) SetImageColorspace(image,RGBColorspace);
      (void) TransformImageColorspace(image,sRGBColorspace);
    }
  return(GetFirstImageInList(image));
}
示例#28
0
MagickExport Image *OilPaintImage(const Image *image,const double radius,
  const double sigma,ExceptionInfo *exception)
{
#define NumberPaintBins  256
#define OilPaintImageTag  "OilPaint/Image"

  CacheView
    *image_view,
    *paint_view;

  Image
    *linear_image,
    *paint_image;

  MagickBooleanType
    status;

  MagickOffsetType
    progress;

  size_t
    **histograms,
    width;

  ssize_t
    center,
    y;

  /*
    Initialize painted image attributes.
  */
  assert(image != (const Image *) NULL);
  assert(image->signature == MagickCoreSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickCoreSignature);
  width=GetOptimalKernelWidth2D(radius,sigma);
  linear_image=CloneImage(image,0,0,MagickTrue,exception);
  paint_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
  if ((linear_image == (Image *) NULL) || (paint_image == (Image *) NULL))
    {
      if (linear_image != (Image *) NULL)
        linear_image=DestroyImage(linear_image);
      if (paint_image != (Image *) NULL)
        linear_image=DestroyImage(paint_image);
      return((Image *) NULL);
    }
  if (SetImageStorageClass(paint_image,DirectClass,exception) == MagickFalse)
    {
      linear_image=DestroyImage(linear_image);
      paint_image=DestroyImage(paint_image);
      return((Image *) NULL);
    }
  histograms=AcquireHistogramThreadSet(NumberPaintBins);
  if (histograms == (size_t **) NULL)
    {
      linear_image=DestroyImage(linear_image);
      paint_image=DestroyImage(paint_image);
      ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
    }
  /*
    Oil paint image.
  */
  status=MagickTrue;
  progress=0;
  center=(ssize_t) GetPixelChannels(linear_image)*(linear_image->columns+width)*
    (width/2L)+GetPixelChannels(linear_image)*(width/2L);
  image_view=AcquireVirtualCacheView(linear_image,exception);
  paint_view=AcquireAuthenticCacheView(paint_image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(static,4) shared(progress,status) \
    magick_threads(linear_image,paint_image,linear_image->rows,1)
#endif
  for (y=0; y < (ssize_t) linear_image->rows; y++)
  {
    register const Quantum
      *restrict p;

    register Quantum
      *restrict q;

    register size_t
      *histogram;

    register ssize_t
      x;

    if (status == MagickFalse)
      continue;
    p=GetCacheViewVirtualPixels(image_view,-((ssize_t) width/2L),y-(ssize_t)
      (width/2L),linear_image->columns+width,width,exception);
    q=QueueCacheViewAuthenticPixels(paint_view,0,y,paint_image->columns,1,
      exception);
    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
      {
        status=MagickFalse;
        continue;
      }
    histogram=histograms[GetOpenMPThreadId()];
    for (x=0; x < (ssize_t) linear_image->columns; x++)
    {
      register ssize_t
        i,
        u;

      size_t
        count;

      ssize_t
        j,
        k,
        n,
        v;

      /*
        Assign most frequent color.
      */
      k=0;
      j=0;
      count=0;
      (void) ResetMagickMemory(histogram,0,NumberPaintBins* sizeof(*histogram));
      for (v=0; v < (ssize_t) width; v++)
      {
        for (u=0; u < (ssize_t) width; u++)
        {
          n=(ssize_t) ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(
            linear_image,p+GetPixelChannels(linear_image)*(u+k))));
          histogram[n]++;
          if (histogram[n] > count)
            {
              j=k+u;
              count=histogram[n];
            }
        }
        k+=(ssize_t) (linear_image->columns+width);
      }
      for (i=0; i < (ssize_t) GetPixelChannels(linear_image); i++)
      {
        PixelChannel channel=GetPixelChannelChannel(linear_image,i);
        PixelTrait traits=GetPixelChannelTraits(linear_image,channel);
        PixelTrait paint_traits=GetPixelChannelTraits(paint_image,channel);
        if ((traits == UndefinedPixelTrait) ||
            (paint_traits == UndefinedPixelTrait))
          continue;
        if (((paint_traits & CopyPixelTrait) != 0) ||
            (GetPixelReadMask(linear_image,p) == 0))
          {
            SetPixelChannel(paint_image,channel,p[center+i],q);
            continue;
          }
        SetPixelChannel(paint_image,channel,p[j*GetPixelChannels(linear_image)+
          i],q);
      }
      p+=GetPixelChannels(linear_image);
      q+=GetPixelChannels(paint_image);
    }
    if (SyncCacheViewAuthenticPixels(paint_view,exception) == MagickFalse)
      status=MagickFalse;
    if (linear_image->progress_monitor != (MagickProgressMonitor) NULL)
      {
        MagickBooleanType
          proceed;

#if defined(MAGICKCORE_OPENMP_SUPPORT)
        #pragma omp critical (MagickCore_OilPaintImage)
#endif
        proceed=SetImageProgress(linear_image,OilPaintImageTag,progress++,
          linear_image->rows);
        if (proceed == MagickFalse)
          status=MagickFalse;
      }
  }
  paint_view=DestroyCacheView(paint_view);
  image_view=DestroyCacheView(image_view);
  histograms=DestroyHistogramThreadSet(histograms);
  linear_image=DestroyImage(linear_image);
  if (status == MagickFalse)
    paint_image=DestroyImage(paint_image);
  return(paint_image);
}
示例#29
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   C o n v e r t H S B T o R G B                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ConvertHSBToRGB() transforms a (hue, saturation, brightness) to a (red,
%  green, blue) triple.
%
%  The format of the ConvertHSBToRGBImage method is:
%
%      void ConvertHSBToRGB(const double hue,const double saturation,
%        const double brightness,Quantum *red,Quantum *green,Quantum *blue)
%
%  A description of each parameter follows:
%
%    o hue, saturation, brightness: A double value representing a
%      component of the HSB color space.
%
%    o red, green, blue: A pointer to a pixel component of type Quantum.
%
*/
MagickExport void ConvertHSBToRGB(const double hue,const double saturation,
  const double brightness,Quantum *red,Quantum *green,Quantum *blue)
{
  MagickRealType
    f,
    h,
    p,
    q,
    t;

  /*
    Convert HSB to RGB colorspace.
  */
  assert(red != (Quantum *) NULL);
  assert(green != (Quantum *) NULL);
  assert(blue != (Quantum *) NULL);
  if (saturation == 0.0)
    {
      *red=ClampToQuantum((MagickRealType) QuantumRange*brightness);
      *green=(*red);
      *blue=(*red);
      return;
    }
  h=6.0*(hue-floor(hue));
  f=h-floor((double) h);
  p=brightness*(1.0-saturation);
  q=brightness*(1.0-saturation*f);
  t=brightness*(1.0-(saturation*(1.0-f)));
  switch ((int) h)
  {
    case 0:
    default:
    {
      *red=ClampToQuantum((MagickRealType) QuantumRange*brightness);
      *green=ClampToQuantum((MagickRealType) QuantumRange*t);
      *blue=ClampToQuantum((MagickRealType) QuantumRange*p);
      break;
    }
    case 1:
    {
      *red=ClampToQuantum((MagickRealType) QuantumRange*q);
      *green=ClampToQuantum((MagickRealType) QuantumRange*brightness);
      *blue=ClampToQuantum((MagickRealType) QuantumRange*p);
      break;
    }
    case 2:
    {
      *red=ClampToQuantum((MagickRealType) QuantumRange*p);
      *green=ClampToQuantum((MagickRealType) QuantumRange*brightness);
      *blue=ClampToQuantum((MagickRealType) QuantumRange*t);
      break;
    }
    case 3:
    {
      *red=ClampToQuantum((MagickRealType) QuantumRange*p);
      *green=ClampToQuantum((MagickRealType) QuantumRange*q);
      *blue=ClampToQuantum((MagickRealType) QuantumRange*brightness);
      break;
    }
    case 4:
    {
      *red=ClampToQuantum((MagickRealType) QuantumRange*t);
      *green=ClampToQuantum((MagickRealType) QuantumRange*p);
      *blue=ClampToQuantum((MagickRealType) QuantumRange*brightness);
      break;
    }
    case 5:
    {
      *red=ClampToQuantum((MagickRealType) QuantumRange*brightness);
      *green=ClampToQuantum((MagickRealType) QuantumRange*p);
      *blue=ClampToQuantum((MagickRealType) QuantumRange*q);
      break;
    }
  }
}
示例#30
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R a i s e I m a g e                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RaiseImage() creates a simulated three-dimensional button-like effect
%  by lightening and darkening the edges of the image.  Members width and
%  height of raise_info define the width of the vertical and horizontal
%  edge of the effect.
%
%  The format of the RaiseImage method is:
%
%      MagickBooleanType RaiseImage(const Image *image,
%        const RectangleInfo *raise_info,const MagickBooleanType raise)
%
%  A description of each parameter follows:
%
%    o image: the image.
%
%    o raise_info: Define the width and height of the raise area.
%
%    o raise: A value other than zero creates a 3-D raise effect,
%      otherwise it has a lowered effect.
%
*/
MagickExport MagickBooleanType RaiseImage(Image *image,
  const RectangleInfo *raise_info,const MagickBooleanType raise)
{
#define AccentuateFactor  ScaleCharToQuantum(135)
#define HighlightFactor  ScaleCharToQuantum(190)
#define ShadowFactor  ScaleCharToQuantum(190)
#define RaiseImageTag  "Raise/Image"
#define TroughFactor  ScaleCharToQuantum(135)

  CacheView
    *image_view;

  ExceptionInfo
    *exception;

  MagickBooleanType
    status;

  MagickOffsetType
    progress;

  Quantum
    foreground,
    background;

  ssize_t
    y;

  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(raise_info != (RectangleInfo *) NULL);
  if ((image->columns <= (raise_info->width << 1)) ||
      (image->rows <= (raise_info->height << 1)))
    ThrowBinaryException(OptionError,"ImageSizeMustExceedBevelWidth",
      image->filename);
  foreground=(Quantum) QuantumRange;
  background=(Quantum) 0;
  if (raise == MagickFalse)
    {
      foreground=(Quantum) 0;
      background=(Quantum) QuantumRange;
    }
  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
    return(MagickFalse);
  /*
    Raise image.
  */
  status=MagickTrue;
  progress=0;
  exception=(&image->exception);
  image_view=AcquireCacheView(image);
#if defined(MAGICKCORE_OPENMP_SUPPORT) 
  #pragma omp parallel for schedule(dynamic,4) shared(progress,status) omp_throttle(1)
#endif
  for (y=0; y < (ssize_t) raise_info->height; y++)
  {
    register ssize_t
      x;

    register PixelPacket
      *restrict q;

    if (status == MagickFalse)
      continue;
    q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
    if (q == (PixelPacket *) NULL)
      {
        status=MagickFalse;
        continue;
      }
    for (x=0; x < y; x++)
    {
      q->red=ClampToQuantum(QuantumScale*((MagickRealType) q->red*
        HighlightFactor+(MagickRealType) foreground*(QuantumRange-
        HighlightFactor)));
      q->green=ClampToQuantum(QuantumScale*((MagickRealType) q->green*
        HighlightFactor+(MagickRealType) foreground*(QuantumRange-
        HighlightFactor)));
      q->blue=ClampToQuantum(QuantumScale*((MagickRealType) q->blue*
        HighlightFactor+(MagickRealType) foreground*(QuantumRange-
        HighlightFactor)));
      q++;
    }
    for ( ; x < (ssize_t) (image->columns-y); x++)
    {
      q->red=ClampToQuantum(QuantumScale*((MagickRealType) q->red*
        AccentuateFactor+(MagickRealType) foreground*(QuantumRange-
        AccentuateFactor)));
      q->green=ClampToQuantum(QuantumScale*((MagickRealType) q->green*
        AccentuateFactor+(MagickRealType) foreground*(QuantumRange-
        AccentuateFactor)));
      q->blue=ClampToQuantum(QuantumScale*((MagickRealType) q->blue*
        AccentuateFactor+(MagickRealType) foreground*(QuantumRange-
        AccentuateFactor)));
      q++;
    }
    for ( ; x < (ssize_t) image->columns; x++)
    {
      q->red=ClampToQuantum(QuantumScale*((MagickRealType) q->red*ShadowFactor+
        (MagickRealType) background*(QuantumRange-ShadowFactor)));
      q->green=ClampToQuantum(QuantumScale*((MagickRealType) q->green*
        ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
      q->blue=ClampToQuantum(QuantumScale*((MagickRealType) q->blue*
        ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
      q++;
    }
    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
      status=MagickFalse;
    if (image->progress_monitor != (MagickProgressMonitor) NULL)
      {
        MagickBooleanType
          proceed;

        proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows);
        if (proceed == MagickFalse)
          status=MagickFalse;
      }
  }
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(dynamic,4) shared(progress,status) omp_throttle(1)
#endif
  for (y=(ssize_t) raise_info->height; y < (ssize_t) (image->rows-raise_info->height); y++)
  {
    register ssize_t
      x;

    register PixelPacket
      *restrict q;

    if (status == MagickFalse)
      continue;
    q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
    if (q == (PixelPacket *) NULL)
      {
        status=MagickFalse;
        continue;
      }
    for (x=0; x < (ssize_t) raise_info->width; x++)
    {
      q->red=ClampToQuantum(QuantumScale*((MagickRealType) q->red*
        HighlightFactor+(MagickRealType) foreground*(QuantumRange-
        HighlightFactor)));
      q->green=ClampToQuantum(QuantumScale*((MagickRealType) q->green*
        HighlightFactor+(MagickRealType) foreground*(QuantumRange-
        HighlightFactor)));
      q->blue=ClampToQuantum(QuantumScale*((MagickRealType) q->blue*
        HighlightFactor+(MagickRealType) foreground*(QuantumRange-
        HighlightFactor)));
      q++;
    }
    for ( ; x < (ssize_t) (image->columns-raise_info->width); x++)
      q++;
    for ( ; x < (ssize_t) image->columns; x++)
    {
      q->red=ClampToQuantum(QuantumScale*((MagickRealType) q->red*ShadowFactor+
        (MagickRealType) background*(QuantumRange-ShadowFactor)));
      q->green=ClampToQuantum(QuantumScale*((MagickRealType) q->green*
        ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
      q->blue=ClampToQuantum(QuantumScale*((MagickRealType) q->blue*
        ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
      q++;
    }
    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
      status=MagickFalse;
    if (image->progress_monitor != (MagickProgressMonitor) NULL)
      {
        MagickBooleanType
          proceed;

        proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows);
        if (proceed == MagickFalse)
          status=MagickFalse;
      }
  }
#if defined(MAGICKCORE_OPENMP_SUPPORT) 
  #pragma omp parallel for schedule(dynamic,4) shared(progress,status) omp_throttle(1)
#endif
  for (y=(ssize_t) (image->rows-raise_info->height); y < (ssize_t) image->rows; y++)
  {
    register ssize_t
      x;

    register PixelPacket
      *restrict q;

    if (status == MagickFalse)
      continue;
    q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
    if (q == (PixelPacket *) NULL)
      {
        status=MagickFalse;
        continue;
      }
    for (x=0; x < (ssize_t) (image->rows-y); x++)
    {
      q->red=ClampToQuantum(QuantumScale*((MagickRealType) q->red*
        HighlightFactor+(MagickRealType) foreground*(QuantumRange-
        HighlightFactor)));
      q->green=ClampToQuantum(QuantumScale*((MagickRealType) q->green*
        HighlightFactor+(MagickRealType) foreground*(QuantumRange-
        HighlightFactor)));
      q->blue=ClampToQuantum(QuantumScale*((MagickRealType) q->blue*
        HighlightFactor+(MagickRealType) foreground*(QuantumRange-
        HighlightFactor)));
      q++;
    }
    for ( ; x < (ssize_t) (image->columns-(image->rows-y)); x++)
    {
      q->red=ClampToQuantum(QuantumScale*((MagickRealType) q->red*TroughFactor+
        (MagickRealType) background*(QuantumRange-TroughFactor)));
      q->green=ClampToQuantum(QuantumScale*((MagickRealType) q->green*
        TroughFactor+(MagickRealType) background*(QuantumRange-TroughFactor)));
      q->blue=ClampToQuantum(QuantumScale*((MagickRealType) q->blue*
        TroughFactor+(MagickRealType) background*(QuantumRange-TroughFactor)));
      q++;
    }
    for ( ; x < (ssize_t) image->columns; x++)
    {
      q->red=ClampToQuantum(QuantumScale*((MagickRealType) q->red*ShadowFactor+
        (MagickRealType) background*(QuantumRange-ShadowFactor)));
      q->green=ClampToQuantum(QuantumScale*((MagickRealType) q->green*
        ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
      q->blue=ClampToQuantum(QuantumScale*((MagickRealType) q->blue*
        ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
      q++;
    }
    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
      status=MagickFalse;
    if (image->progress_monitor != (MagickProgressMonitor) NULL)
      {
        MagickBooleanType
          proceed;

#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp critical (MagickCore_RaiseImage)
#endif
        proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows);
        if (proceed == MagickFalse)
          status=MagickFalse;
      }
  }
  image_view=DestroyCacheView(image_view);
  return(status);
}