Ejemplo n.º 1
0
static inline void PlasmaPixel(Image *image,RandomInfo *random_info,double x,
  double y)
{
  ExceptionInfo
    *exception;

  QuantumAny
    range;

  register PixelPacket
    *q;

  exception=(&image->exception);
  q=GetAuthenticPixels(image,(ssize_t) ceil(x-0.5),(ssize_t) ceil(y-0.5),1,1,
    exception);
  if (q == (PixelPacket *) NULL)
    return;
  range=GetQuantumRange(16UL);
  q->red=ScaleAnyToQuantum((size_t) (65535.0*
    GetPseudoRandomValue(random_info)+0.5),range);
  q->green=ScaleAnyToQuantum((size_t) (65535.0*
    GetPseudoRandomValue(random_info)+0.5),range);
  q->blue=ScaleAnyToQuantum((size_t) (65535.0*
    GetPseudoRandomValue(random_info)+0.5),range);
  (void) SyncAuthenticPixels(image,exception);
}
Ejemplo n.º 2
0
MagickExport MagickBooleanType SetImageChannelDepth(Image *image,
  const ChannelType channel,const unsigned long depth)
{
  CacheView
    *image_view;

  ExceptionInfo
    *exception;

  long
    y;

  MagickBooleanType
    status;

  QuantumAny
    range;

  assert(image != (Image *) NULL);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  assert(image->signature == MagickSignature);
  if (GetImageDepth(image,&image->exception) <= (unsigned long)
      MagickMin((double) depth,(double) MAGICKCORE_QUANTUM_DEPTH))
    {
      image->depth=depth;
      return(MagickTrue);
    }
  /*
    Scale pixels to desired depth.
  */
  status=MagickTrue;
  range=GetQuantumRange(depth);
  exception=(&image->exception);
  image_view=AcquireCacheView(image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(dynamic,4) shared(status)
#endif
  for (y=0; y < (long) image->rows; y++)
  {
    register IndexPacket
      *restrict indexes;

    register long
      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);
    for (x=0; x < (long) image->columns; x++)
    {
      if ((channel & RedChannel) != 0)
        q->red=ScaleAnyToQuantum(ScaleQuantumToAny(q->red,range),range);
      if ((channel & GreenChannel) != 0)
        q->green=ScaleAnyToQuantum(ScaleQuantumToAny(q->green,range),range);
      if ((channel & BlueChannel) != 0)
        q->blue=ScaleAnyToQuantum(ScaleQuantumToAny(q->blue,range),range);
      if (((channel & OpacityChannel) != 0) && (image->matte != MagickFalse))
        q->opacity=ScaleAnyToQuantum(ScaleQuantumToAny(q->opacity,range),range);
      if (((channel & IndexChannel) != 0) &&
          (image->colorspace == CMYKColorspace))
        indexes[x]=ScaleAnyToQuantum(ScaleQuantumToAny(indexes[x],range),range);
      q++;
    }
    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
      {
        status=MagickFalse;
        continue;
      }
  }
  image_view=DestroyCacheView(image_view);
  if (image->storage_class == PseudoClass)
    {
      QuantumAny
        range;

      register long
        i;

      register PixelPacket
        *restrict p;

      p=image->colormap;
      range=GetQuantumRange(depth);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(dynamic,4) shared(status)
#endif
      for (i=0; i < (long) image->colors; i++)
      {
        if ((channel & RedChannel) != 0)
          p->red=ScaleAnyToQuantum(ScaleQuantumToAny(p->red,range),range);
        if ((channel & GreenChannel) != 0)
          p->green=ScaleAnyToQuantum(ScaleQuantumToAny(p->green,range),range);
        if ((channel & BlueChannel) != 0)
          p->blue=ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,range),range);
        if ((channel & OpacityChannel) != 0)
          p->opacity=ScaleAnyToQuantum(ScaleQuantumToAny(p->opacity,range),
            range);
        p++;
      }
    }
Ejemplo n.º 3
0
MagickExport unsigned long GetImageChannelDepth(const Image *image,
  const ChannelType channel,ExceptionInfo *exception)
{
  CacheView
    *image_view;

  long
    y;

  MagickBooleanType
    status;

  register long
    id;

  unsigned long
    *current_depth,
    depth,
    number_threads;

  /*
    Compute image depth.
  */
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  number_threads=GetOpenMPMaximumThreads();
  current_depth=(unsigned long *) AcquireQuantumMemory(number_threads,
    sizeof(*current_depth));
  if (current_depth == (unsigned long *) NULL)
    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
  status=MagickTrue;
  for (id=0; id < (long) number_threads; id++)
    current_depth[id]=1;
  if ((image->storage_class == PseudoClass) && (image->matte == MagickFalse))
    {
      register const PixelPacket
        *restrict p;

      register long
        i;

      p=image->colormap;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(dynamic,4) shared(status)
#endif
      for (i=0; i < (long) image->colors; i++)
      {
        if (status == MagickFalse)
          continue;
        id=GetOpenMPThreadId();
        while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
        {
          MagickStatusType
            status;

          QuantumAny
            range;

          status=0;
          range=GetQuantumRange(current_depth[id]);
          if ((channel & RedChannel) != 0)
            status|=p->red != ScaleAnyToQuantum(ScaleQuantumToAny(p->red,
              range),range);
          if ((channel & GreenChannel) != 0)
            status|=p->green != ScaleAnyToQuantum(ScaleQuantumToAny(p->green,
              range),range);
          if ((channel & BlueChannel) != 0)
            status|=p->blue != ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,
              range),range);
          if (status == 0)
            break;
          current_depth[id]++;
        }
        p++;
      }
      depth=current_depth[0];
      for (id=1; id < (long) number_threads; id++)
        if (depth < current_depth[id])
          depth=current_depth[id];
      current_depth=(unsigned long *) RelinquishMagickMemory(current_depth);
      return(depth);
    }
  image_view=AcquireCacheView(image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(dynamic,4) shared(status)
#endif
  for (y=0; y < (long) image->rows; y++)
  {
    register const IndexPacket
      *restrict indexes;

    register const PixelPacket
      *restrict p;

    register long
      id,
      x;

    if (status == MagickFalse)
      continue;
    id=GetOpenMPThreadId();
    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
    if (p == (const PixelPacket *) NULL)
      continue;
    indexes=GetCacheViewVirtualIndexQueue(image_view);
    for (x=0; x < (long) image->columns; x++)
    {
      while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
      {
        MagickStatusType
          status;

        QuantumAny
          range;

        status=0;
        range=GetQuantumRange(current_depth[id]);
        if ((channel & RedChannel) != 0)
          status|=p->red != ScaleAnyToQuantum(ScaleQuantumToAny(p->red,range),
            range);
        if ((channel & GreenChannel) != 0)
          status|=p->green != ScaleAnyToQuantum(ScaleQuantumToAny(p->green,
            range),range);
        if ((channel & BlueChannel) != 0)
          status|=p->blue != ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,range),
            range);
        if (((channel & OpacityChannel) != 0) && (image->matte != MagickFalse))
          status|=p->opacity != ScaleAnyToQuantum(ScaleQuantumToAny(p->opacity,
            range),range);
        if (((channel & IndexChannel) != 0) &&
            (image->colorspace == CMYKColorspace))
          status|=indexes[x] != ScaleAnyToQuantum(ScaleQuantumToAny(indexes[x],
            range),range);
        if (status == 0)
          break;
        current_depth[id]++;
      }
      p++;
    }
    if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
      status=MagickFalse;
  }
  image_view=DestroyCacheView(image_view);
  depth=current_depth[0];
  for (id=1; id < (long) number_threads; id++)
    if (depth < current_depth[id])
      depth=current_depth[id];
  current_depth=(unsigned long *) RelinquishMagickMemory(current_depth);
  return(depth);
}
Ejemplo n.º 4
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e F I T S I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteFITSImage() writes a Flexible Image Transport System image to a
%  file as gray scale intensities [0..255].
%
%  The format of the WriteFITSImage method is:
%
%      MagickBooleanType WriteFITSImage(const ImageInfo *image_info,
%        Image *image)
%
%  A description of each parameter follows.
%
%    o image_info: the image info.
%
%    o image:  The image.
%
*/
static MagickBooleanType WriteFITSImage(const ImageInfo *image_info,
                                        Image *image)
{
    char
    header[FITSBlocksize],
           *fits_info;

    MagickBooleanType
    status;

    QuantumInfo
    *quantum_info;

    register const PixelPacket
    *p;

    size_t
    length;

    ssize_t
    count,
    offset,
    y;

    unsigned char
    *pixels;

    /*
      Open output image file.
    */
    assert(image_info != (const ImageInfo *) NULL);
    assert(image_info->signature == MagickSignature);
    assert(image != (Image *) NULL);
    assert(image->signature == MagickSignature);
    if (image->debug != MagickFalse)
        (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
    if (status == MagickFalse)
        return(status);
    if (IsRGBColorspace(image->colorspace) == MagickFalse)
        (void) TransformImageColorspace(image,RGBColorspace);
    /*
      Allocate image memory.
    */
    fits_info=(char *) AcquireQuantumMemory(FITSBlocksize,sizeof(*fits_info));
    if (fits_info == (char *) NULL)
        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
    (void) ResetMagickMemory(fits_info,' ',FITSBlocksize*sizeof(*fits_info));
    /*
      Initialize image header.
    */
    image->depth=GetImageQuantumDepth(image,MagickFalse);
    quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
    if (quantum_info == (QuantumInfo *) NULL)
        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
    offset=0;
    (void) FormatLocaleString(header,FITSBlocksize,
                              "SIMPLE  =                    T");
    (void) strncpy(fits_info+offset,header,strlen(header));
    offset+=80;
    (void) FormatLocaleString(header,FITSBlocksize,"BITPIX  =           %10ld",
                              (long) (quantum_info->format == FloatingPointQuantumFormat ? -1 : 1)*
                              image->depth);
    (void) strncpy(fits_info+offset,header,strlen(header));
    offset+=80;
    (void) FormatLocaleString(header,FITSBlocksize,"NAXIS   =           %10lu",
                              IsGrayImage(image,&image->exception) != MagickFalse ? 2UL : 3UL);
    (void) strncpy(fits_info+offset,header,strlen(header));
    offset+=80;
    (void) FormatLocaleString(header,FITSBlocksize,"NAXIS1  =           %10lu",
                              (unsigned long) image->columns);
    (void) strncpy(fits_info+offset,header,strlen(header));
    offset+=80;
    (void) FormatLocaleString(header,FITSBlocksize,"NAXIS2  =           %10lu",
                              (unsigned long) image->rows);
    (void) strncpy(fits_info+offset,header,strlen(header));
    offset+=80;
    if (IsGrayImage(image,&image->exception) == MagickFalse)
    {
        (void) FormatLocaleString(header,FITSBlocksize,
                                  "NAXIS3  =           %10lu",3UL);
        (void) strncpy(fits_info+offset,header,strlen(header));
        offset+=80;
    }
    (void) FormatLocaleString(header,FITSBlocksize,"BSCALE  =         %E",1.0);
    (void) strncpy(fits_info+offset,header,strlen(header));
    offset+=80;
    (void) FormatLocaleString(header,FITSBlocksize,"BZERO   =         %E",
                              image->depth > 8 ? GetFITSPixelRange(image->depth) : 0.0);
    (void) strncpy(fits_info+offset,header,strlen(header));
    offset+=80;
    (void) FormatLocaleString(header,FITSBlocksize,"DATAMAX =         %E",
                              1.0*((MagickOffsetType) GetQuantumRange(image->depth)));
    (void) strncpy(fits_info+offset,header,strlen(header));
    offset+=80;
    (void) FormatLocaleString(header,FITSBlocksize,"DATAMIN =         %E",0.0);
    (void) strncpy(fits_info+offset,header,strlen(header));
    offset+=80;
    if (image->endian == LSBEndian)
    {
        (void) FormatLocaleString(header,FITSBlocksize,"XENDIAN = 'SMALL'");
        (void) strncpy(fits_info+offset,header,strlen(header));
        offset+=80;
    }
    (void) FormatLocaleString(header,FITSBlocksize,"HISTORY %.72s",
                              GetMagickVersion((size_t *) NULL));
    (void) strncpy(fits_info+offset,header,strlen(header));
    offset+=80;
    (void) strncpy(header,"END",FITSBlocksize);
    (void) strncpy(fits_info+offset,header,strlen(header));
    offset+=80;
    (void) WriteBlob(image,FITSBlocksize,(unsigned char *) fits_info);
    /*
      Convert image to fits scale PseudoColor class.
    */
    pixels=GetQuantumPixels(quantum_info);
    if (IsGrayImage(image,&image->exception) != MagickFalse)
    {
        length=GetQuantumExtent(image,quantum_info,GrayQuantum);
        for (y=(ssize_t) image->rows-1; y >= 0; y--)
        {
            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
            if (p == (const PixelPacket *) NULL)
                break;
            length=ExportQuantumPixels(image,(const CacheView *) NULL,quantum_info,
                                       GrayQuantum,pixels,&image->exception);
            if (image->depth == 16)
                SetFITSUnsignedPixels(image->columns,image->depth,pixels);
            if (((image->depth == 32) || (image->depth == 64)) &&
                    (quantum_info->format != FloatingPointQuantumFormat))
                SetFITSUnsignedPixels(image->columns,image->depth,pixels);
            count=WriteBlob(image,length,pixels);
            if (count != (ssize_t) length)
                break;
            status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
                                    image->rows);
            if (status == MagickFalse)
                break;
        }
    }
    else
    {
        length=GetQuantumExtent(image,quantum_info,RedQuantum);
        for (y=(ssize_t) image->rows-1; y >= 0; y--)
        {
            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
            if (p == (const PixelPacket *) NULL)
                break;
            length=ExportQuantumPixels(image,(const CacheView *) NULL,quantum_info,
                                       RedQuantum,pixels,&image->exception);
            if (image->depth == 16)
                SetFITSUnsignedPixels(image->columns,image->depth,pixels);
            if (((image->depth == 32) || (image->depth == 64)) &&
                    (quantum_info->format != FloatingPointQuantumFormat))
                SetFITSUnsignedPixels(image->columns,image->depth,pixels);
            count=WriteBlob(image,length,pixels);
            if (count != (ssize_t) length)
                break;
            status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
                                    image->rows);
            if (status == MagickFalse)
                break;
        }
        length=GetQuantumExtent(image,quantum_info,GreenQuantum);
        for (y=(ssize_t) image->rows-1; y >= 0; y--)
        {
            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
            if (p == (const PixelPacket *) NULL)
                break;
            length=ExportQuantumPixels(image,(const CacheView *) NULL,quantum_info,
                                       GreenQuantum,pixels,&image->exception);
            if (image->depth == 16)
                SetFITSUnsignedPixels(image->columns,image->depth,pixels);
            if (((image->depth == 32) || (image->depth == 64)) &&
                    (quantum_info->format != FloatingPointQuantumFormat))
                SetFITSUnsignedPixels(image->columns,image->depth,pixels);
            count=WriteBlob(image,length,pixels);
            if (count != (ssize_t) length)
                break;
            status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
                                    image->rows);
            if (status == MagickFalse)
                break;
        }
        length=GetQuantumExtent(image,quantum_info,BlueQuantum);
        for (y=(ssize_t) image->rows-1; y >= 0; y--)
        {
            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
            if (p == (const PixelPacket *) NULL)
                break;
            length=ExportQuantumPixels(image,(const CacheView *) NULL,quantum_info,
                                       BlueQuantum,pixels,&image->exception);
            if (image->depth == 16)
                SetFITSUnsignedPixels(image->columns,image->depth,pixels);
            if (((image->depth == 32) || (image->depth == 64)) &&
                    (quantum_info->format != FloatingPointQuantumFormat))
                SetFITSUnsignedPixels(image->columns,image->depth,pixels);
            count=WriteBlob(image,length,pixels);
            if (count != (ssize_t) length)
                break;
            status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
                                    image->rows);
            if (status == MagickFalse)
                break;
        }
    }
    quantum_info=DestroyQuantumInfo(quantum_info);
    length=(size_t) (FITSBlocksize-TellBlob(image) % FITSBlocksize);
    if (length != 0)
    {
        (void) ResetMagickMemory(fits_info,0,length*sizeof(*fits_info));
        (void) WriteBlob(image,length,(unsigned char *) fits_info);
    }
    fits_info=DestroyString(fits_info);
    (void) CloseBlob(image);
    return(MagickTrue);
}
Ejemplo n.º 5
0
static inline double GetFITSPixelRange(const size_t depth)
{
    return((double) ((MagickOffsetType) GetQuantumRange(depth)));
}
Ejemplo n.º 6
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e T X T I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteTXTImage writes the pixel values as text numbers.
%
%  The format of the WriteTXTImage method is:
%
%      MagickBooleanType WriteTXTImage(const ImageInfo *image_info,Image *image)
%
%  A description of each parameter follows.
%
%    o image_info: the image info.
%
%    o image:  The image.
%
*/
static MagickBooleanType WriteTXTImage(const ImageInfo *image_info,Image *image)
{
  char
    buffer[MaxTextExtent],
    colorspace[MaxTextExtent],
    tuple[MaxTextExtent];

  long
    y;

  MagickBooleanType
    status;

  MagickPixelPacket
    pixel;

  register const IndexPacket
    *indexes;

  register const PixelPacket
    *p;

  register long
    x;

  /*
    Open output image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  status=OpenBlob(image_info,image,WriteBlobMode,&image->exception);
  if (status == MagickFalse)
    return(status);
  (void) CopyMagickString(colorspace,MagickOptionToMnemonic(
    MagickColorspaceOptions,(long) image->colorspace),MaxTextExtent);
  LocaleLower(colorspace);
  image->depth=GetImageQuantumDepth(image,MagickTrue);
  if (image->matte != MagickFalse)
    (void) ConcatenateMagickString(colorspace,"a",MaxTextExtent);
  (void) FormatMagickString(buffer,MaxTextExtent,
    "# ImageMagick pixel enumeration: %lu,%lu,%lu,%s\n",image->columns,
    image->rows,(unsigned long) GetQuantumRange(image->depth),colorspace);
  (void) WriteBlobString(image,buffer);
  GetMagickPixelPacket(image,&pixel);
  for (y=0; y < (long) image->rows; y++)
  {
    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
    if (p == (const PixelPacket *) NULL)
      break;
    indexes=GetVirtualIndexQueue(image);
    for (x=0; x < (long) image->columns; x++)
    {
      (void) FormatMagickString(buffer,MaxTextExtent,"%ld,%ld: ",x,y);
      (void) WriteBlobString(image,buffer);
      SetMagickPixelPacket(image,p,indexes+x,&pixel);
      (void) CopyMagickString(tuple,"(",MaxTextExtent);
      ConcatenateColorComponent(&pixel,RedChannel,X11Compliance,tuple);
      (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
      ConcatenateColorComponent(&pixel,GreenChannel,X11Compliance,tuple);
      (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
      ConcatenateColorComponent(&pixel,BlueChannel,X11Compliance,tuple);
      if (pixel.colorspace == CMYKColorspace)
        {
          (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
          ConcatenateColorComponent(&pixel,IndexChannel,X11Compliance,tuple);
        }
      if (pixel.matte != MagickFalse)
        {
          (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
          ConcatenateColorComponent(&pixel,AlphaChannel,X11Compliance,tuple);
        }
      (void) ConcatenateMagickString(tuple,")",MaxTextExtent);
      (void) WriteBlobString(image,tuple);
      (void) WriteBlobString(image,"  ");
      GetColorTuple(&pixel,MagickTrue,tuple);
      (void) FormatMagickString(buffer,MaxTextExtent,"%s",tuple);
      (void) WriteBlobString(image,buffer);
      (void) WriteBlobString(image,"  ");
      (void) QueryMagickColorname(image,&pixel,SVGCompliance,tuple,
        &image->exception);
      (void) WriteBlobString(image,tuple);
      (void) WriteBlobString(image,"\n");
      p++;
    }
    status=SetImageProgress(image,SaveImageTag,y,image->rows);
    if (status == MagickFalse)
      break;
  }
  (void) CloseBlob(image);
  return(MagickTrue);
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d T X T I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadTXTImage() reads a text file and returns it as an image.  It allocates
%  the memory necessary for the new Image structure and returns a pointer to
%  the new image.
%
%  The format of the ReadTXTImage method is:
%
%      Image *ReadTXTImage(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 *ReadTXTImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  char
    colorspace[MaxTextExtent],
    text[MaxTextExtent];

  Image
    *image;

  IndexPacket
    *indexes;

  long
    type,
    x_offset,
    y,
    y_offset;

  MagickBooleanType
    status;

  MagickPixelPacket
    pixel;

  QuantumAny
    range;

  register ssize_t
    i,
    x;

  register PixelPacket
    *q;

  ssize_t
    count;

  unsigned long
    depth,
    height,
    max_value,
    width;

  /*
    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);
    }
  (void) ResetMagickMemory(text,0,sizeof(text));
  (void) ReadBlobString(image,text);
  if (LocaleNCompare((char *) text,MagickID,strlen(MagickID)) != 0)
    return(ReadTEXTImage(image_info,image,text,exception));
  do
  {
    width=0;
    height=0;
    max_value=0;
    *colorspace='\0';
    count=(ssize_t) sscanf(text+32,"%lu,%lu,%lu,%s",&width,&height,&max_value,
      colorspace);
    if ((count != 4) || (width == 0) || (height == 0) || (max_value == 0))
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    image->columns=width;
    image->rows=height;
    for (depth=1; (GetQuantumRange(depth)+1) < max_value; depth++) ;
    image->depth=depth;
    LocaleLower(colorspace);
    i=(ssize_t) strlen(colorspace)-1;
    image->matte=MagickFalse;
    if ((i > 0) && (colorspace[i] == 'a'))
      {
        colorspace[i]='\0';
        image->matte=MagickTrue;
      }
    type=ParseCommandOption(MagickColorspaceOptions,MagickFalse,colorspace);
    if (type < 0)
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    image->colorspace=(ColorspaceType) type;
    (void) ResetMagickMemory(&pixel,0,sizeof(pixel));
    (void) SetImageBackgroundColor(image);
    range=GetQuantumRange(image->depth);
    for (y=0; y < (ssize_t) image->rows; y++)
    {
      double
        blue,
        green,
        index,
        opacity,
        red;

      red=0.0;
      green=0.0;
      blue=0.0;
      index=0.0;
      opacity=0.0;
      for (x=0; x < (ssize_t) image->columns; x++)
      {
        if (ReadBlobString(image,text) == (char *) NULL)
          break;
        switch (image->colorspace)
        {
          case GRAYColorspace:
          {
            if (image->matte != MagickFalse)
              {
                count=(ssize_t) sscanf(text,"%ld,%ld: (%lf%*[%,]%lf%*[%,]",
                  &x_offset,&y_offset,&red,&opacity);
                green=red;
                blue=red;
                break;
              }
            count=(ssize_t) sscanf(text,"%ld,%ld: (%lf%*[%,]",&x_offset,
              &y_offset,&red);
            green=red;
            blue=red;
            break;
          }
          case CMYKColorspace:
          {
            if (image->matte != MagickFalse)
              {
                count=(ssize_t) sscanf(text,
                  "%ld,%ld: (%lf%*[%,]%lf%*[%,]%lf%*[%,]%lf%*[%,]%lf%*[%,]",
                  &x_offset,&y_offset,&red,&green,&blue,&index,&opacity);
                break;
              }
            count=(ssize_t) sscanf(text,
              "%ld,%ld: (%lf%*[%,]%lf%*[%,]%lf%*[%,]%lf%*[%,]",&x_offset,
              &y_offset,&red,&green,&blue,&index);
            break;
          }
          default:
          {
            if (image->matte != MagickFalse)
              {
                count=(ssize_t) sscanf(text,
                  "%ld,%ld: (%lf%*[%,]%lf%*[%,]%lf%*[%,]%lf%*[%,]",
                  &x_offset,&y_offset,&red,&green,&blue,&opacity);
                break;
              }
            count=(ssize_t) sscanf(text,
              "%ld,%ld: (%lf%*[%,]%lf%*[%,]%lf%*[%,]",&x_offset,&y_offset,
               &red,&green,&blue);
            break;
          }
        }
        if (strchr(text,'%') != (char *) NULL)
          {
            red*=0.01*range;
            green*=0.01*range;
            blue*=0.01*range;
            index*=0.01*range;
            opacity*=0.01*range;
          }
        if (image->colorspace == LabColorspace)
          {
            green+=(range+1)/2.0;
            blue+=(range+1)/2.0;
          }
        pixel.red=ScaleAnyToQuantum((QuantumAny) (red+0.5),range);
        pixel.green=ScaleAnyToQuantum((QuantumAny) (green+0.5),range);
        pixel.blue=ScaleAnyToQuantum((QuantumAny) (blue+0.5),range);
        pixel.index=ScaleAnyToQuantum((QuantumAny) (index+0.5),range);
        pixel.opacity=ScaleAnyToQuantum((QuantumAny) (opacity+0.5),range);
        q=GetAuthenticPixels(image,x_offset,y_offset,1,1,exception);
        if (q == (PixelPacket *) NULL)
          continue;
        SetPixelRed(q,pixel.red);
        SetPixelGreen(q,pixel.green);
        SetPixelBlue(q,pixel.blue);
        if (image->colorspace == CMYKColorspace)
          {
            indexes=GetAuthenticIndexQueue(image);
            SetPixelIndex(indexes,pixel.index);
          }
        if (image->matte != MagickFalse)
          SetPixelAlpha(q,pixel.opacity);
        if (SyncAuthenticPixels(image,exception) == MagickFalse)
          break;
      }
    }
    (void) ReadBlobString(image,text);
    if (LocaleNCompare((char *) text,MagickID,strlen(MagickID)) == 0)
      {
        /*
          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;
      }
  } while (LocaleNCompare((char *) text,MagickID,strlen(MagickID)) == 0);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}
Ejemplo n.º 9
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e T X T I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteTXTImage writes the pixel values as text numbers.
%
%  The format of the WriteTXTImage method is:
%
%      MagickBooleanType WriteTXTImage(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 WriteTXTImage(const ImageInfo *image_info,Image *image,
                                       ExceptionInfo *exception)
{
    char
    buffer[MagickPathExtent],
           colorspace[MagickPathExtent],
           tuple[MagickPathExtent];

    MagickBooleanType
    status;

    MagickOffsetType
    scene;

    PixelInfo
    pixel;

    register const Quantum
    *p;

    register ssize_t
    x;

    ssize_t
    y;

    /*
      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);
    status=OpenBlob(image_info,image,WriteBlobMode,exception);
    if (status == MagickFalse)
        return(status);
    scene=0;
    do
    {
        ComplianceType
        compliance;

        const char
        *value;

        (void) CopyMagickString(colorspace,CommandOptionToMnemonic(
                                    MagickColorspaceOptions,(ssize_t) image->colorspace),MagickPathExtent);
        LocaleLower(colorspace);
        image->depth=GetImageQuantumDepth(image,MagickTrue);
        if (image->alpha_trait != UndefinedPixelTrait)
            (void) ConcatenateMagickString(colorspace,"a",MagickPathExtent);
        compliance=NoCompliance;
        value=GetImageOption(image_info,"txt:compliance");
        if (value != (char *) NULL)
            compliance=(ComplianceType) ParseCommandOption(MagickComplianceOptions,
                       MagickFalse,value);
        if (LocaleCompare(image_info->magick,"SPARSE-COLOR") != 0)
        {
            size_t
            depth;

            depth=compliance == SVGCompliance ? image->depth :
                  MAGICKCORE_QUANTUM_DEPTH;
            (void) FormatLocaleString(buffer,MagickPathExtent,
                                      "# ImageMagick pixel enumeration: %.20g,%.20g,%.20g,%s\n",(double)
                                      image->columns,(double) image->rows,(double) ((MagickOffsetType)
                                              GetQuantumRange(depth)),colorspace);
            (void) WriteBlobString(image,buffer);
        }
        GetPixelInfo(image,&pixel);
        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; x++)
            {
                GetPixelInfoPixel(image,p,&pixel);
                if (pixel.colorspace == LabColorspace)
                {
                    pixel.green-=(QuantumRange+1)/2.0;
                    pixel.blue-=(QuantumRange+1)/2.0;
                }
                if (LocaleCompare(image_info->magick,"SPARSE-COLOR") == 0)
                {
                    /*
                      Sparse-color format.
                    */
                    if (GetPixelAlpha(image,p) == (Quantum) OpaqueAlpha)
                    {
                        GetColorTuple(&pixel,MagickFalse,tuple);
                        (void) FormatLocaleString(buffer,MagickPathExtent,
                                                  "%.20g,%.20g,",(double) x,(double) y);
                        (void) WriteBlobString(image,buffer);
                        (void) WriteBlobString(image,tuple);
                        (void) WriteBlobString(image," ");
                    }
                    p+=GetPixelChannels(image);
                    continue;
                }
                (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g,%.20g: ",
                                          (double) x,(double) y);
                (void) WriteBlobString(image,buffer);
                (void) CopyMagickString(tuple,"(",MagickPathExtent);
                if (pixel.colorspace == GRAYColorspace)
                    ConcatenateColorComponent(&pixel,GrayPixelChannel,compliance,
                                              tuple);
                else
                {
                    ConcatenateColorComponent(&pixel,RedPixelChannel,compliance,tuple);
                    (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
                    ConcatenateColorComponent(&pixel,GreenPixelChannel,compliance,
                                              tuple);
                    (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
                    ConcatenateColorComponent(&pixel,BluePixelChannel,compliance,tuple);
                }
                if (pixel.colorspace == CMYKColorspace)
                {
                    (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
                    ConcatenateColorComponent(&pixel,BlackPixelChannel,compliance,
                                              tuple);
                }
                if (pixel.alpha_trait != UndefinedPixelTrait)
                {
                    (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
                    ConcatenateColorComponent(&pixel,AlphaPixelChannel,compliance,
                                              tuple);
                }
                (void) ConcatenateMagickString(tuple,")",MagickPathExtent);
                (void) WriteBlobString(image,tuple);
                (void) WriteBlobString(image,"  ");
                GetColorTuple(&pixel,MagickTrue,tuple);
                (void) FormatLocaleString(buffer,MagickPathExtent,"%s",tuple);
                (void) WriteBlobString(image,buffer);
                (void) WriteBlobString(image,"  ");
                (void) QueryColorname(image,&pixel,SVGCompliance,tuple,exception);
                (void) WriteBlobString(image,tuple);
                (void) WriteBlobString(image,"\n");
                p+=GetPixelChannels(image);
            }
            status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
                                    image->rows);
            if (status == MagickFalse)
                break;
        }
        if (GetNextImageInList(image) == (Image *) NULL)
            break;
        image=SyncNextImageInList(image);
        status=SetImageProgress(image,SaveImagesTag,scene++,
                                GetImageListLength(image));
        if (status == MagickFalse)
            break;
    } while (image_info->adjoin != MagickFalse);
    (void) CloseBlob(image);
    return(MagickTrue);
}
Ejemplo n.º 10
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d T X T I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadTXTImage() reads a text file and returns it as an image.  It allocates
%  the memory necessary for the new Image structure and returns a pointer to
%  the new image.
%
%  The format of the ReadTXTImage method is:
%
%      Image *ReadTXTImage(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 *ReadTXTImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
    char
    colorspace[MagickPathExtent],
               text[MagickPathExtent];

    Image
    *image;

    long
    x_offset,
    y_offset;

    PixelInfo
    pixel;

    MagickBooleanType
    status;

    QuantumAny
    range;

    register ssize_t
    i,
    x;

    register Quantum
    *q;

    ssize_t
    count,
    type,
    y;

    unsigned long
    depth,
    height,
    max_value,
    width;

    /*
      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)
    {
        image=DestroyImageList(image);
        return((Image *) NULL);
    }
    (void) ResetMagickMemory(text,0,sizeof(text));
    (void) ReadBlobString(image,text);
    if (LocaleNCompare((char *) text,MagickID,strlen(MagickID)) != 0)
        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    do
    {
        width=0;
        height=0;
        max_value=0;
        *colorspace='\0';
        count=(ssize_t) sscanf(text+32,"%lu,%lu,%lu,%s",&width,&height,&max_value,
                               colorspace);
        if ((count != 4) || (width == 0) || (height == 0) || (max_value == 0))
            ThrowReaderException(CorruptImageError,"ImproperImageHeader");
        image->columns=width;
        image->rows=height;
        for (depth=1; (GetQuantumRange(depth)+1) < max_value; depth++) ;
        image->depth=depth;
        status=SetImageExtent(image,image->columns,image->rows,exception);
        if (status == MagickFalse)
            return(DestroyImageList(image));
        LocaleLower(colorspace);
        i=(ssize_t) strlen(colorspace)-1;
        image->alpha_trait=UndefinedPixelTrait;
        if ((i > 0) && (colorspace[i] == 'a'))
        {
            colorspace[i]='\0';
            image->alpha_trait=BlendPixelTrait;
        }
        type=ParseCommandOption(MagickColorspaceOptions,MagickFalse,colorspace);
        if (type < 0)
            ThrowReaderException(CorruptImageError,"ImproperImageHeader");
        (void) SetImageBackgroundColor(image,exception);
        (void) SetImageColorspace(image,(ColorspaceType) type,exception);
        GetPixelInfo(image,&pixel);
        range=GetQuantumRange(image->depth);
        for (y=0; y < (ssize_t) image->rows; y++)
        {
            double
            alpha,
            black,
            blue,
            green,
            red;

            red=0.0;
            green=0.0;
            blue=0.0;
            black=0.0;
            alpha=0.0;
            for (x=0; x < (ssize_t) image->columns; x++)
            {
                if (ReadBlobString(image,text) == (char *) NULL)
                    break;
                switch (image->colorspace)
                {
                case GRAYColorspace:
                {
                    if (image->alpha_trait != UndefinedPixelTrait)
                    {
                        count=(ssize_t) sscanf(text,"%ld,%ld: (%lf%*[%,]%lf%*[%,]",
                                               &x_offset,&y_offset,&red,&alpha);
                        green=red;
                        blue=red;
                        break;
                    }
                    count=(ssize_t) sscanf(text,"%ld,%ld: (%lf%*[%,]",&x_offset,
                                           &y_offset,&red);
                    green=red;
                    blue=red;
                    break;
                }
                case CMYKColorspace:
                {
                    if (image->alpha_trait != UndefinedPixelTrait)
                    {
                        count=(ssize_t) sscanf(text,
                                               "%ld,%ld: (%lf%*[%,]%lf%*[%,]%lf%*[%,]%lf%*[%,]%lf%*[%,]",
                                               &x_offset,&y_offset,&red,&green,&blue,&black,&alpha);
                        break;
                    }
                    count=(ssize_t) sscanf(text,
                                           "%ld,%ld: (%lf%*[%,]%lf%*[%,]%lf%*[%,]%lf%*[%,]",&x_offset,
                                           &y_offset,&red,&green,&blue,&black);
                    break;
                }
                default:
                {
                    if (image->alpha_trait != UndefinedPixelTrait)
                    {
                        count=(ssize_t) sscanf(text,
                                               "%ld,%ld: (%lf%*[%,]%lf%*[%,]%lf%*[%,]%lf%*[%,]",
                                               &x_offset,&y_offset,&red,&green,&blue,&alpha);
                        break;
                    }
                    count=(ssize_t) sscanf(text,
                                           "%ld,%ld: (%lf%*[%,]%lf%*[%,]%lf%*[%,]",&x_offset,
                                           &y_offset,&red,&green,&blue);
                    break;
                }
                }
                if (strchr(text,'%') != (char *) NULL)
                {
                    red*=0.01*range;
                    green*=0.01*range;
                    blue*=0.01*range;
                    black*=0.01*range;
                    alpha*=0.01*range;
                }
                if (image->colorspace == LabColorspace)
                {
                    green+=(range+1)/2.0;
                    blue+=(range+1)/2.0;
                }
                pixel.red=(MagickRealType) ScaleAnyToQuantum((QuantumAny) (red+0.5),
                          range);
                pixel.green=(MagickRealType) ScaleAnyToQuantum((QuantumAny) (green+0.5),
                            range);
                pixel.blue=(MagickRealType) ScaleAnyToQuantum((QuantumAny) (blue+0.5),
                           range);
                pixel.black=(MagickRealType) ScaleAnyToQuantum((QuantumAny) (black+0.5),
                            range);
                pixel.alpha=(MagickRealType) ScaleAnyToQuantum((QuantumAny) (alpha+0.5),
                            range);
                q=GetAuthenticPixels(image,(ssize_t) x_offset,(ssize_t) y_offset,1,1,
                                     exception);
                if (q == (Quantum *) NULL)
                    continue;
                SetPixelViaPixelInfo(image,&pixel,q);
                if (SyncAuthenticPixels(image,exception) == MagickFalse)
                    break;
            }
        }
        (void) ReadBlobString(image,text);
        if (LocaleNCompare((char *) text,MagickID,strlen(MagickID)) == 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 (LocaleNCompare((char *) text,MagickID,strlen(MagickID)) == 0);
    (void) CloseBlob(image);
    return(GetFirstImageInList(image));
}
Ejemplo n.º 11
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e J P 2 I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteJP2Image() writes an image in the JPEG 2000 image format.
%
%  JP2 support originally written by Nathan Brown, [email protected]
%
%  The format of the WriteJP2Image method is:
%
%      MagickBooleanType WriteJP2Image(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 WriteJP2Image(const ImageInfo *image_info,Image *image,
  ExceptionInfo *exception)
{
  char
    *key,
    magick[MaxTextExtent],
    *options;

  const char
    *option;

  jas_image_cmptparm_t
    component_info[4];

  jas_image_t
    *jp2_image;

  jas_matrix_t
    *pixels[4];

  jas_stream_t
    *jp2_stream;

  MagickBooleanType
    status;

  QuantumAny
    range;

  register const Quantum
    *p;

  register ssize_t
    i,
    x;

  size_t
    number_components;

  ssize_t
    format,
    y;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  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);
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
  if (status == MagickFalse)
    return(status);
  /*
    Initialize JPEG 2000 API.
  */
  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
    (void) TransformImageColorspace(image,sRGBColorspace,exception);
  jp2_stream=JP2StreamManager(image);
  if (jp2_stream == (jas_stream_t *) NULL)
    ThrowWriterException(DelegateError,"UnableToManageJP2Stream");
  number_components=image->alpha_trait ? 4UL : 3UL;
  if (IsGrayColorspace(image->colorspace) != MagickFalse)
    number_components=1;
  if ((image->columns != (unsigned int) image->columns) ||
      (image->rows != (unsigned int) image->rows))
    ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
  (void) ResetMagickMemory(&component_info,0,sizeof(component_info));
  for (i=0; i < (ssize_t) number_components; i++)
  {
    component_info[i].tlx=0;
    component_info[i].tly=0;
    component_info[i].hstep=1;
    component_info[i].vstep=1;
    component_info[i].width=(unsigned int) image->columns;
    component_info[i].height=(unsigned int) image->rows;
    component_info[i].prec=(int) MagickMax(MagickMin(image->depth,16),2);
    component_info[i].sgnd=MagickFalse;
  }
  jp2_image=jas_image_create((int) number_components,component_info,
    JAS_CLRSPC_UNKNOWN);
  if (jp2_image == (jas_image_t *) NULL)
    ThrowWriterException(DelegateError,"UnableToCreateImage");
  switch (image->colorspace)
  {
    case RGBColorspace:
    case sRGBColorspace:
    {
      /*
        RGB colorspace.
      */
      jas_image_setclrspc(jp2_image,JAS_CLRSPC_SRGB);
      jas_image_setcmpttype(jp2_image,0,
        (jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
      jas_image_setcmpttype(jp2_image,1,
        (jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
      jas_image_setcmpttype(jp2_image,2,
        (jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
      if (number_components == 4)
        jas_image_setcmpttype(jp2_image,3,JAS_IMAGE_CT_OPACITY);
      break;
    }
    case GRAYColorspace:
    {
      /*
        Grayscale colorspace.
      */
      jas_image_setclrspc(jp2_image,JAS_CLRSPC_SGRAY);
      jas_image_setcmpttype(jp2_image,0,
        JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
      break;
    }
    case YCbCrColorspace:
    {
      /*
        YCbCr colorspace.
      */
      jas_image_setclrspc(jp2_image,JAS_CLRSPC_SYCBCR);
      jas_image_setcmpttype(jp2_image,0,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(0));
      jas_image_setcmpttype(jp2_image,1,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(1));
      jas_image_setcmpttype(jp2_image,2,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(2));
      if (number_components == 4)
        jas_image_setcmpttype(jp2_image,3,JAS_IMAGE_CT_OPACITY);
      break;
    }
    case XYZColorspace:
    {
      /*
        XYZ colorspace.
      */
      jas_image_setclrspc(jp2_image,JAS_CLRSPC_CIEXYZ);
      jas_image_setcmpttype(jp2_image,0,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(0));
      jas_image_setcmpttype(jp2_image,1,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(1));
      jas_image_setcmpttype(jp2_image,2,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(2));
      if (number_components == 4)
        jas_image_setcmpttype(jp2_image,3,JAS_IMAGE_CT_OPACITY);
      break;
    }
    case LabColorspace:
    {
      /*
        Lab colorspace.
      */
      jas_image_setclrspc(jp2_image,JAS_CLRSPC_CIELAB);
      jas_image_setcmpttype(jp2_image,0,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(0));
      jas_image_setcmpttype(jp2_image,1,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(1));
      jas_image_setcmpttype(jp2_image,2,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(2));
      if (number_components == 4)
        jas_image_setcmpttype(jp2_image,3,JAS_IMAGE_CT_OPACITY);
      break;
    }
    default:
    {
      /*
        Unknow.
      */
      jas_image_setclrspc(jp2_image,JAS_CLRSPC_UNKNOWN);
      jas_image_setcmpttype(jp2_image,0,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(0));
      jas_image_setcmpttype(jp2_image,1,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(1));
      jas_image_setcmpttype(jp2_image,2,(jas_image_cmpttype_t)
        JAS_IMAGE_CT_COLOR(2));
      if (number_components == 4)
        jas_image_setcmpttype(jp2_image,3,JAS_IMAGE_CT_OPACITY);
      break;
    }
  }
  /*
    Convert to JPEG 2000 pixels.
  */
  for (i=0; i < (ssize_t) number_components; i++)
  {
    pixels[i]=jas_matrix_create(1,(int) image->columns);
    if (pixels[i] == (jas_matrix_t *) NULL)
      {
        for (x=0; x < i; x++)
          jas_matrix_destroy(pixels[x]);
        jas_image_destroy(jp2_image);
        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
      }
  }
  range=GetQuantumRange((size_t) component_info[0].prec);
  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; x++)
    {
      if (number_components == 1)
        jas_matrix_setv(pixels[0],x,(jas_seqent_t) ScaleQuantumToAny(
          GetPixelIntensity(image,p),range));
      else
        {
          jas_matrix_setv(pixels[0],x,(jas_seqent_t) ScaleQuantumToAny(
            GetPixelRed(image,p),range));
          jas_matrix_setv(pixels[1],x,(jas_seqent_t) ScaleQuantumToAny(
            GetPixelGreen(image,p),range));
          jas_matrix_setv(pixels[2],x,(jas_seqent_t) ScaleQuantumToAny(
            GetPixelBlue(image,p),range));
          if (number_components > 3)
            jas_matrix_setv(pixels[3],x,(jas_seqent_t) ScaleQuantumToAny(
              GetPixelAlpha(image,p),range));
        }
      p+=GetPixelChannels(image);
    }
    for (i=0; i < (ssize_t) number_components; i++)
      (void) jas_image_writecmpt(jp2_image,(short) i,0,(unsigned int) y,
        (unsigned int) image->columns,1,pixels[i]);
    status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
      image->rows);
    if (status == MagickFalse)
      break;
  }
  (void) CopyMagickString(magick,image_info->magick,MaxTextExtent);
  if (LocaleCompare(magick,"J2C") == 0)
    (void) CopyMagickString(magick,"JPC",MaxTextExtent);
  LocaleLower(magick);
  format=jas_image_strtofmt(magick);
  options=(char *) NULL;
  ResetImageOptionIterator(image_info);
  key=GetNextImageOption(image_info);
  for ( ; key != (char *) NULL; key=GetNextImageOption(image_info))
  {
    option=GetImageOption(image_info,key);
    if (option == (const char *) NULL)
      continue;
    if (LocaleNCompare(key,"jp2:",4) == 0)
      {
        (void) ConcatenateString(&options,key+4);
        if (*option != '\0')
          {
            (void) ConcatenateString(&options,"=");
            (void) ConcatenateString(&options,option);
          }
        (void) ConcatenateString(&options," ");
      }
  }
  option=GetImageOption(image_info,"jp2:rate");
  if ((option == (const char *) NULL) &&
      (image_info->compression != LosslessJPEGCompression) &&
      (image->quality != UndefinedCompressionQuality) &&
      ((double) image->quality <= 99.5) &&
      ((image->rows*image->columns) > 2500))
    {
      char
        option[MaxTextExtent];

      double
        alpha,
        header_size,
        number_pixels,
        rate,
        target_size;

      alpha=115.0-image->quality;
      rate=100.0/(alpha*alpha);
      header_size=550.0;
      header_size+=(number_components-1)*142;
      number_pixels=(double) image->rows*image->columns*number_components*
        (GetImageQuantumDepth(image,MagickTrue)/8);
      target_size=(number_pixels*rate)+header_size;
      rate=target_size/number_pixels;
      (void) FormatLocaleString(option,MaxTextExtent,"rate=%g",rate);
      (void) ConcatenateString(&options,option);
    }
  status=jas_image_encode(jp2_image,jp2_stream,format,options) != 0 ?
    MagickTrue : MagickFalse;
  if (options != (char *) NULL)
    options=DestroyString(options);
  (void) jas_stream_close(jp2_stream);
  for (i=0; i < (ssize_t) number_components; i++)
    jas_matrix_destroy(pixels[i]);
  jas_image_destroy(jp2_image);
  if (status != MagickFalse)
    ThrowWriterException(DelegateError,"UnableToEncodeImageFile");
  return(MagickTrue);
}
Ejemplo n.º 12
0
static Image *ReadJP2Image(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image;

  jas_cmprof_t
    *cm_profile;

  jas_iccprof_t
    *icc_profile;

  jas_image_t
    *jp2_image;

  jas_matrix_t
    *pixels[4];

  jas_stream_t
    *jp2_stream;

  MagickBooleanType
    status;

  QuantumAny
    pixel,
    range[4];

  register Quantum
    *q;

  register ssize_t
    i,
    x;

  size_t
    maximum_component_depth,
    number_components,
    x_step[4],
    y_step[4];

  ssize_t
    components[4],
    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,exception);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
    Initialize JPEG 2000 API.
  */
  jp2_stream=JP2StreamManager(image);
  if (jp2_stream == (jas_stream_t *) NULL)
    ThrowReaderException(DelegateError,"UnableToManageJP2Stream");
  jp2_image=jas_image_decode(jp2_stream,-1,0);
  if (jp2_image == (jas_image_t *) NULL)
    {
      (void) jas_stream_close(jp2_stream);
      ThrowReaderException(DelegateError,"UnableToDecodeImageFile");
    }
  image->columns=jas_image_width(jp2_image);
  image->rows=jas_image_height(jp2_image);
  image->compression=JPEG2000Compression;
  switch (jas_clrspc_fam(jas_image_clrspc(jp2_image)))
  {
    case JAS_CLRSPC_FAM_RGB:
    {
      SetImageColorspace(image,RGBColorspace,exception);
      components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_R);
      components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_G);
      components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_B);
      if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
        {
          (void) jas_stream_close(jp2_stream);
          jas_image_destroy(jp2_image);
          ThrowReaderException(CorruptImageError,"MissingImageChannel");
        }
      number_components=3;
      components[3]=jas_image_getcmptbytype(jp2_image,3);
      if (components[3] > 0)
        {
          image->alpha_trait=BlendPixelTrait;
          number_components++;
        }
      break;
    }
    case JAS_CLRSPC_FAM_GRAY:
    {
      SetImageColorspace(image,GRAYColorspace,exception);
      components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_GRAY_Y);
      if (components[0] < 0)
        {
          (void) jas_stream_close(jp2_stream);
          jas_image_destroy(jp2_image);
          ThrowReaderException(CorruptImageError,"MissingImageChannel");
        }
      number_components=1;
      break;
    }
    case JAS_CLRSPC_FAM_YCBCR:
    {
      SetImageColorspace(image,YCbCrColorspace,exception);
      components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_Y);
      components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CB);
      components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CR);
      if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
        {
          (void) jas_stream_close(jp2_stream);
          jas_image_destroy(jp2_image);
          ThrowReaderException(CorruptImageError,"MissingImageChannel");
        }
      number_components=3;
      components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN);
      if (components[3] > 0)
        {
          image->alpha_trait=BlendPixelTrait;
          number_components++;
        }
      break;
    }
    case JAS_CLRSPC_FAM_XYZ:
    {
      SetImageColorspace(image,XYZColorspace,exception);
      components[0]=jas_image_getcmptbytype(jp2_image,0);
      components[1]=jas_image_getcmptbytype(jp2_image,1);
      components[2]=jas_image_getcmptbytype(jp2_image,2);
      if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
        {
          (void) jas_stream_close(jp2_stream);
          jas_image_destroy(jp2_image);
          ThrowReaderException(CorruptImageError,"MissingImageChannel");
        }
      number_components=3;
      components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN);
      if (components[3] > 0)
        {
          image->alpha_trait=BlendPixelTrait;
          number_components++;
        }
      break;
    }
    case JAS_CLRSPC_FAM_LAB:
    {
      SetImageColorspace(image,LabColorspace,exception);
      components[0]=jas_image_getcmptbytype(jp2_image,0);
      components[1]=jas_image_getcmptbytype(jp2_image,1);
      components[2]=jas_image_getcmptbytype(jp2_image,2);
      if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
        {
          (void) jas_stream_close(jp2_stream);
          jas_image_destroy(jp2_image);
          ThrowReaderException(CorruptImageError,"MissingImageChannel");
        }
      number_components=3;
      components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN);
      if (components[3] > 0)
        {
          image->alpha_trait=BlendPixelTrait;
          number_components++;
        }
      break;
    }
    default:
    {
      (void) jas_stream_close(jp2_stream);
      jas_image_destroy(jp2_image);
      ThrowReaderException(CoderError,"ColorspaceModelIsNotSupported");
    }
  }
  for (i=0; i < (ssize_t) number_components; i++)
  {
    size_t
      height,
      width;

    width=(size_t) (jas_image_cmptwidth(jp2_image,components[i])*
      jas_image_cmpthstep(jp2_image,components[i]));
    height=(size_t) (jas_image_cmptheight(jp2_image,components[i])*
      jas_image_cmptvstep(jp2_image,components[i]));
    x_step[i]=(unsigned int) jas_image_cmpthstep(jp2_image,components[i]);
    y_step[i]=(unsigned int) jas_image_cmptvstep(jp2_image,components[i]);
    if ((width != image->columns) || (height != image->rows) ||
        (jas_image_cmpttlx(jp2_image,components[i]) != 0) ||
        (jas_image_cmpttly(jp2_image,components[i]) != 0) ||
        (jas_image_cmptsgnd(jp2_image,components[i]) != MagickFalse))
      {
        (void) jas_stream_close(jp2_stream);
        jas_image_destroy(jp2_image);
        ThrowReaderException(CoderError,"IrregularChannelGeometryNotSupported");
      }
  }
  /*
    Convert JPEG 2000 pixels.
  */
  image->alpha_trait=number_components > 3 ? BlendPixelTrait :
    UndefinedPixelTrait;
  maximum_component_depth=0;
  for (i=0; i < (ssize_t) number_components; i++)
  {
    maximum_component_depth=(unsigned int) MagickMax((size_t)
      jas_image_cmptprec(jp2_image,components[i]),(size_t)
      maximum_component_depth);
    pixels[i]=jas_matrix_create(1,(int) (image->columns/x_step[i]));
    if (pixels[i] == (jas_matrix_t *) NULL)
      {
        for (--i; i >= 0; i--)
          jas_matrix_destroy(pixels[i]);
        jas_image_destroy(jp2_image);
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
      }
  }
  image->depth=maximum_component_depth;
  if (image_info->ping != MagickFalse)
    {
      (void) jas_stream_close(jp2_stream);
      jas_image_destroy(jp2_image);
      return(GetFirstImageInList(image));
    }
  for (i=0; i < (ssize_t) number_components; i++)
    range[i]=GetQuantumRange((size_t) jas_image_cmptprec(jp2_image,
      components[i]));
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
    if (q == (Quantum *) NULL)
      break;
    for (i=0; i < (ssize_t) number_components; i++)
      (void) jas_image_readcmpt(jp2_image,(short) components[i],0,
        (jas_image_coord_t) (y/y_step[i]),(jas_image_coord_t) (image->columns/
        x_step[i]),1,pixels[i]);
    switch (number_components)
    {
      case 1:
      {
        /*
          Grayscale.
        */
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]);
          SetPixelGray(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q);
          q+=GetPixelChannels(image);
        }
        break;
      }
      case 3:
      {
        /*
          RGB.
        */
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]);
          SetPixelRed(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q);
          pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]);
          SetPixelGreen(image,ScaleAnyToQuantum((QuantumAny) pixel,range[1]),q);
          pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]);
          SetPixelBlue(image,ScaleAnyToQuantum((QuantumAny) pixel,range[2]),q);
          q+=GetPixelChannels(image);
        }
        break;
      }
      case 4:
      {
        /*
          RGBA.
        */
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]);
          SetPixelRed(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q);
          pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]);
          SetPixelGreen(image,ScaleAnyToQuantum((QuantumAny) pixel,range[1]),q);
          pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]);
          SetPixelBlue(image,ScaleAnyToQuantum((QuantumAny) pixel,range[2]),q);
          pixel=(QuantumAny) jas_matrix_getv(pixels[3],x/x_step[3]);
          SetPixelAlpha(image,ScaleAnyToQuantum((QuantumAny) pixel,range[3]),q);
          q+=GetPixelChannels(image);
        }
        break;
      }
    }
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
    status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
      image->rows);
    if (status == MagickFalse)
      break;
  }
  cm_profile=jas_image_cmprof(jp2_image);
  icc_profile=(jas_iccprof_t *) NULL;
  if (cm_profile != (jas_cmprof_t *) NULL)
    icc_profile=jas_iccprof_createfromcmprof(cm_profile);
  if (icc_profile != (jas_iccprof_t *) NULL)
    {
      jas_stream_t
        *icc_stream;

      icc_stream=jas_stream_memopen(NULL,0);
      if ((icc_stream != (jas_stream_t *) NULL) &&
          (jas_iccprof_save(icc_profile,icc_stream) == 0) &&
          (jas_stream_flush(icc_stream) == 0))
        {
          jas_stream_memobj_t
            *blob;

          StringInfo
            *icc_profile,
            *profile;

          /*
            Extract the icc profile, handle errors without much noise.
          */
          blob=(jas_stream_memobj_t *) icc_stream->obj_;
          if (image->debug != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "Profile: ICC, %.20g bytes",(double) blob->len_);
          profile=BlobToStringInfo(blob->buf_,blob->len_);
          if (profile == (StringInfo *) NULL)
            ThrowReaderException(CorruptImageError,"MemoryAllocationFailed");
          icc_profile=(StringInfo *) GetImageProfile(image,"icc");
          if (icc_profile == (StringInfo *) NULL)
            (void) SetImageProfile(image,"icc",profile,exception);
          else
            (void) ConcatenateStringInfo(icc_profile,profile);
          profile=DestroyStringInfo(profile);
          (void) jas_stream_close(icc_stream);
        }
    }
  (void) jas_stream_close(jp2_stream);
  jas_image_destroy(jp2_image);
  for (i=0; i < (ssize_t) number_components; i++)
    jas_matrix_destroy(pixels[i]);
  return(GetFirstImageInList(image));
}
Ejemplo n.º 13
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e J P 2 I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteJP2Image() writes an image in the JPEG 2000 image format.
%
%  JP2 support originally written by Nathan Brown, [email protected]
%
%  The format of the WriteJP2Image method is:
%
%      MagickBooleanType WriteJP2Image(const ImageInfo *image_info,Image *image)
%
%  A description of each parameter follows.
%
%    o image_info: the image info.
%
%    o image:  The image.
%
*/
static MagickBooleanType WriteJP2Image(const ImageInfo *image_info,Image *image)
{
  char
    *key,
    magick[MaxTextExtent],
    *options;

  const char
    *option;

  long
    format,
    y;

  jas_image_cmptparm_t
    component_info[4];

  jas_image_t
    *jp2_image;

  jas_matrix_t
    *pixels[4];

  jas_stream_t
    *jp2_stream;

  MagickBooleanType
    status;

  QuantumAny
    range;

  register const PixelPacket
    *p;

  register long
    i,
    x;

  unsigned short
    *map;

  unsigned long
    number_components;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
  if (status == MagickFalse)
    return(status);
  /*
    Intialize JPEG 2000 API.
  */
  if (image->colorspace != RGBColorspace)
    (void) TransformImageColorspace(image,RGBColorspace);
  jp2_stream=JP2StreamManager(image);
  if (jp2_stream == (jas_stream_t *) NULL)
    ThrowWriterException(DelegateError,"UnableToManageJP2Stream");
  number_components=image->matte ? 4UL : 3UL;
  if ((image_info->type != TrueColorType) &&
      IsGrayImage(image,&image->exception))
    number_components=1;
  if ((image->columns != (unsigned int) image->columns) ||
      (image->rows != (unsigned int) image->rows))
    ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
  (void) ResetMagickMemory(&component_info,0,sizeof(component_info));
  for (i=0; i < (long) number_components; i++)
  {
    component_info[i].tlx=0;
    component_info[i].tly=0;
    component_info[i].hstep=1;
    component_info[i].vstep=1;
    component_info[i].width=(unsigned int) image->columns;
    component_info[i].height=(unsigned int) image->rows;
    component_info[i].prec=(int) MagickMax(MagickMin(image->depth,16),2);
    component_info[i].sgnd=MagickFalse;
    
  }
  jp2_image=jas_image_create((int) number_components,component_info,
    JAS_CLRSPC_UNKNOWN);
  if (jp2_image == (jas_image_t *) NULL)
    ThrowWriterException(DelegateError,"UnableToCreateImage");
  if (number_components == 1)
    {
      /*
        sRGB Grayscale.
      */
      jas_image_setclrspc(jp2_image,JAS_CLRSPC_SGRAY);
      jas_image_setcmpttype(jp2_image,0,
        JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
    }
  else
    {
      /*
        sRGB.
      */
      jas_image_setclrspc(jp2_image,JAS_CLRSPC_SRGB);
      jas_image_setcmpttype(jp2_image,0,
        JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
      jas_image_setcmpttype(jp2_image,1,
        JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
      jas_image_setcmpttype(jp2_image,2,
        JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
      if (number_components == 4)
        jas_image_setcmpttype(jp2_image,3,JAS_IMAGE_CT_OPACITY);
    }
  /*
    Convert to JPEG 2000 pixels.
  */
  for (i=0; i < (long) number_components; i++)
  {
    pixels[i]=jas_matrix_create(1,(int) image->columns);
    if (pixels[i] == (jas_matrix_t *) NULL)
      {
        for (x=0; x < i; x++)
          jas_matrix_destroy(pixels[x]);
        jas_image_destroy(jp2_image);
        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
      }
  }
  range=GetQuantumRange((unsigned long) component_info[0].prec);
  map=(unsigned short *) AcquireQuantumMemory(MaxMap+1,sizeof(*map));
  for (i=0; i <= (long) MaxMap; i++)
    map[i]=(unsigned short) ScaleQuantumToMap((Quantum)
      ScaleQuantumToAny((Quantum) i,range));
  if (map == (unsigned short *) NULL)
    {
      for (i=0; i < (long) number_components; i++)
        jas_matrix_destroy(pixels[i]);
      jas_image_destroy(jp2_image);
      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
    }
  for (y=0; y < (long) image->rows; y++)
  {
    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
    if (p == (const PixelPacket *) NULL)
      break;
    for (x=0; x < (long) image->columns; x++)
    {
      if (number_components == 1)
        jas_matrix_setv(pixels[0],x,map[ScaleQuantumToMap(
          PixelIntensityToQuantum(p))]);
      else
        {
          jas_matrix_setv(pixels[0],x,map[ScaleQuantumToMap(p->red)]);
          jas_matrix_setv(pixels[1],x,map[ScaleQuantumToMap(p->green)]);
          jas_matrix_setv(pixels[2],x,map[ScaleQuantumToMap(p->blue)]);
          if (number_components > 3)
            jas_matrix_setv(pixels[3],x,map[ScaleQuantumToMap((Quantum)
              (QuantumRange-p->opacity))]);
        }
      p++;
    }
    for (i=0; i < (long) number_components; i++)
      (void) jas_image_writecmpt(jp2_image,(short) i,0,(unsigned int) y,
        (unsigned int) image->columns,1,pixels[i]);
    status=SetImageProgress(image,SaveImageTag,y,image->rows);
    if (status == MagickFalse)
      break;
  }
  map=(unsigned short *) RelinquishMagickMemory(map);
  (void) CopyMagickString(magick,image_info->magick,MaxTextExtent);
  LocaleLower(magick);
  format=jas_image_strtofmt(magick);
  options=(char *) NULL;
  ResetImageOptionIterator(image_info);
  key=GetNextImageOption(image_info);
  while (key != (char *) NULL)
  {
    option=GetImageOption(image_info,key);
    if (option != (const char *) NULL)
      {
        if (LocaleNCompare(key,"jp2:",4) == 0)
          {
            (void) ConcatenateString(&options,key+4);
            if (*option != '\0')
              {
                (void) ConcatenateString(&options,"=");
                (void) ConcatenateString(&options,option);
              }
            (void) ConcatenateString(&options," ");
          }
       }
    key=GetNextImageOption(image_info);
  }
  option=GetImageOption(image_info,"jp2:rate");
  if ((option == (const char *) NULL) &&
      (image_info->compression != LosslessJPEGCompression) &&
      (image->quality != UndefinedCompressionQuality) &&
      ((double) image->quality <= 99.5) &&
      ((image->rows*image->columns) > 2500))
    {
      char
        option[MaxTextExtent];

      double
        alpha,
        header_size,
        number_pixels,
        rate,
        target_size;

      alpha=115.0-image->quality;
      rate=100.0/(alpha*alpha);
      header_size=550.0;
      header_size+=(number_components-1)*142;
      number_pixels=(double) image->rows*image->columns*number_components*
        (GetImageQuantumDepth(image,MagickTrue)/8);
      target_size=(number_pixels*rate)+header_size;
      rate=target_size/number_pixels;
      (void) FormatMagickString(option,MaxTextExtent,"rate=%g",rate);
      (void) ConcatenateString(&options,option);
    }
  status=jas_image_encode(jp2_image,jp2_stream,format,options) != 0 ?
    MagickTrue : MagickFalse;
  (void) jas_stream_close(jp2_stream);
  for (i=0; i < (long) number_components; i++)
    jas_matrix_destroy(pixels[i]);
  jas_image_destroy(jp2_image);
  if (status != MagickFalse)
    ThrowWriterException(DelegateError,"UnableToEncodeImageFile");
  return(MagickTrue);
}
Ejemplo n.º 14
0
static Image *ReadJP2Image(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image;

  jas_cmprof_t
    *cm_profile;

  jas_iccprof_t
    *icc_profile;

  jas_image_t
    *jp2_image;

  jas_matrix_t
    *pixels[4];

  jas_stream_t
    *jp2_stream;

  long
    components[4],
    y;

  MagickBooleanType
    status;

  QuantumAny
    pixel,
    *map[4],
    range;

  register long
    i,
    x;

  register PixelPacket
    *q;

  unsigned long
    maximum_component_depth,
    number_components,
    x_step[4],
    y_step[4];

  /*
    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 JPEG 2000 API.
  */
  jp2_stream=JP2StreamManager(image);
  if (jp2_stream == (jas_stream_t *) NULL)
    ThrowReaderException(DelegateError,"UnableToManageJP2Stream");
  jp2_image=jas_image_decode(jp2_stream,-1,0);
  if (jp2_image == (jas_image_t *) NULL)
    {
      (void) jas_stream_close(jp2_stream);
      ThrowReaderException(DelegateError,"UnableToDecodeImageFile");
    }
  switch (jas_clrspc_fam(jas_image_clrspc(jp2_image)))
  {
    case JAS_CLRSPC_FAM_RGB:
    {
      components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_R);
      components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_G);
      components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_B);
      if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
        {
          (void) jas_stream_close(jp2_stream);
          jas_image_destroy(jp2_image);
          ThrowReaderException(CorruptImageError,"MissingImageChannel");
        }
      number_components=3;
      components[3]=jas_image_getcmptbytype(jp2_image,3);
      if (components[3] > 0)
        {
          image->matte=MagickTrue;
          number_components++;
        }
      break;
    }
    case JAS_CLRSPC_FAM_GRAY:
    {
      components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_GRAY_Y);
      if (components[0] < 0)
        {
          (void) jas_stream_close(jp2_stream);
          jas_image_destroy(jp2_image);
          ThrowReaderException(CorruptImageError,"MissingImageChannel");
        }
      number_components=1;
      break;
    }
    case JAS_CLRSPC_FAM_YCBCR:
    {
      components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_Y);
      components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CB);
      components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CR);
      if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
        {
          (void) jas_stream_close(jp2_stream);
          jas_image_destroy(jp2_image);
          ThrowReaderException(CorruptImageError,"MissingImageChannel");
        }
      number_components=3;
      components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN);
      if (components[3] > 0)
        {
          image->matte=MagickTrue;
          number_components++;
        }
      image->colorspace=YCbCrColorspace;
      break;
    }
    default:
    {
      (void) jas_stream_close(jp2_stream);
      jas_image_destroy(jp2_image);
      ThrowReaderException(CoderError,"ColorspaceModelIsNotSupported");
    }
  }
  image->columns=jas_image_width(jp2_image);
  image->rows=jas_image_height(jp2_image);
  image->compression=JPEG2000Compression;
  for (i=0; i < (long) number_components; i++)
  {
    unsigned long
      height,
      width;

    width=(unsigned long) (jas_image_cmptwidth(jp2_image,components[i])*
      jas_image_cmpthstep(jp2_image,components[i]));
    height=(unsigned long) (jas_image_cmptheight(jp2_image,components[i])*
      jas_image_cmptvstep(jp2_image,components[i]));
    x_step[i]=(unsigned int) jas_image_cmpthstep(jp2_image,components[i]);
    y_step[i]=(unsigned int) jas_image_cmptvstep(jp2_image,components[i]);
    if ((width != image->columns) || (height != image->rows) ||
        (jas_image_cmpttlx(jp2_image,components[i]) != 0) ||
        (jas_image_cmpttly(jp2_image,components[i]) != 0) ||
        (x_step[i] != 1) || (y_step[i] != 1) ||
        (jas_image_cmptsgnd(jp2_image,components[i]) != MagickFalse))
      {
        (void) jas_stream_close(jp2_stream);
        jas_image_destroy(jp2_image);
        ThrowReaderException(CoderError,"IrregularChannelGeometryNotSupported");
      }
  }
  /*
    Convert JPEG 2000 pixels.
  */
  image->matte=number_components > 3 ? MagickTrue : MagickFalse;
  maximum_component_depth=0;
  for (i=0; i < (long) number_components; i++)
  {
    maximum_component_depth=(unsigned int) MagickMax((size_t)
      jas_image_cmptprec(jp2_image,components[i]),(size_t)
      maximum_component_depth);
    pixels[i]=jas_matrix_create(1,(int) (image->columns/x_step[i]));
    if (pixels[i] == (jas_matrix_t *) NULL)
      {
        for (--i; i >= 0; i--)
          jas_matrix_destroy(pixels[i]);
        jas_image_destroy(jp2_image);
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
      }
  }
  image->depth=maximum_component_depth;
  if (image_info->ping != MagickFalse)
    {
      (void) jas_stream_close(jp2_stream);
      jas_image_destroy(jp2_image);
      return(GetFirstImageInList(image));
    }
  for (i=0; i < (long) number_components; i++)
  {
    long
      j;

    map[i]=(QuantumAny *) AcquireQuantumMemory(MaxMap+1,sizeof(**map));
    if (map[i] == (QuantumAny *) NULL)
      {
        for (--i; i >= 0; i--)
          map[i]=(QuantumAny *) RelinquishMagickMemory(map[i]);
        for (i=0; i < (long) number_components; i++)
          jas_matrix_destroy(pixels[i]);
        jas_image_destroy(jp2_image);
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
      }
    range=GetQuantumRange((unsigned long) jas_image_cmptprec(jp2_image,
      components[i]));
    for (j=0; j <= (long) MaxMap; j++)
      map[i][j]=ScaleQuantumToMap(ScaleAnyToQuantum((QuantumAny) j,range));
  }
  for (y=0; y < (long) image->rows; y++)
  {
    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
    if (q == (PixelPacket *) NULL)
      break;
    for (i=0; i < (long) number_components; i++)
      (void) jas_image_readcmpt(jp2_image,(short) components[i],0,
        ((unsigned int) y)/y_step[i],((unsigned int) image->columns)/x_step[i],
        1,pixels[i]);
    switch (number_components)
    {
      case 1:
      {
        /*
          Grayscale.
        */
        for (x=0; x < (long) image->columns; x++)
        {
          pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]);
          q->red=(Quantum) map[0][pixel];
          q->green=q->red;
          q->blue=q->red;
          q++;
        }
        break;
      }
      case 3:
      {
        /*
          RGB.
        */
        for (x=0; x < (long) image->columns; x++)
        {
          pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]);
          q->red=(Quantum) map[0][pixel];
          pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]);
          q->green=(Quantum) map[1][pixel];
          pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]);
          q->blue=(Quantum) map[2][pixel];
          q++;
        }
        break;
      }
      case 4:
      {
        /*
          RGBA.
        */
        for (x=0; x < (long) image->columns; x++)
        {
          pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]);
          q->red=(Quantum) map[0][pixel];
          pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]);
          q->green=(Quantum) map[1][pixel];
          pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]);
          q->blue=(Quantum) map[2][pixel];
          pixel=(QuantumAny) jas_matrix_getv(pixels[3],x/x_step[3]);
          q->opacity=(Quantum) (QuantumRange-map[3][pixel]);
          q++;
        }
        break;
      }
    }
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
    status=SetImageProgress(image,LoadImageTag,y,image->rows);
    if (status == MagickFalse)
      break;
  }
  for (i=0; i < (long) number_components; i++)
    map[i]=(QuantumAny *) RelinquishMagickMemory(map[i]);
  cm_profile=jas_image_cmprof(jp2_image);
  icc_profile=(jas_iccprof_t *) NULL;
  if (cm_profile != (jas_cmprof_t *) NULL)
    icc_profile=jas_iccprof_createfromcmprof(cm_profile);
  if (icc_profile != (jas_iccprof_t *) NULL)
    {
      jas_stream_t
        *icc_stream;

      icc_stream=jas_stream_memopen(NULL,0);
      if ((icc_stream != (jas_stream_t *) NULL) &&
          (jas_iccprof_save(icc_profile,icc_stream) == 0) &&
          (jas_stream_flush(icc_stream) == 0))
        {
          StringInfo
            *icc_profile,
            *profile;

          jas_stream_memobj_t
            *blob;

          /*
            Extract the icc profile, handle errors without much noise.
          */
          blob=(jas_stream_memobj_t *) icc_stream->obj_;
          if (image->debug != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "Profile: ICC, %lu bytes",(unsigned long) blob->len_);
          profile=AcquireStringInfo(blob->len_);
          SetStringInfoDatum(profile,blob->buf_);
          icc_profile=(StringInfo *) GetImageProfile(image,"icc");
          if (icc_profile == (StringInfo *) NULL)
            (void) SetImageProfile(image,"icc",profile);
          else
            (void) ConcatenateStringInfo(icc_profile,profile);
          profile=DestroyStringInfo(profile);
          (void) jas_stream_close(icc_stream);
        }
    }
  (void) jas_stream_close(jp2_stream);
  jas_image_destroy(jp2_image);
  for (i=0; i < (long) number_components; i++)
    jas_matrix_destroy(pixels[i]);
  return(GetFirstImageInList(image));
}
Ejemplo n.º 15
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e D E B U G I m a g e                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteDEBUGImage writes the image pixel values with 20 places of precision.
%
%  The format of the WriteDEBUGImage method is:
%
%      MagickBooleanType WriteDEBUGImage(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 WriteDEBUGImage(const ImageInfo *image_info,
  Image *image,ExceptionInfo *exception)
{
  char
    buffer[MaxTextExtent],
    colorspace[MaxTextExtent],
    tuple[MaxTextExtent];

  ssize_t
    y;

  MagickBooleanType
    status;

  MagickOffsetType
    scene;

  PixelInfo
    pixel;

  register const Quantum
    *p;

  register ssize_t
    x;

  /*
    Open output image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  status=OpenBlob(image_info,image,WriteBlobMode,exception);
  if (status == MagickFalse)
    return(status);
  scene=0;
  do
  {
    (void) CopyMagickString(colorspace,CommandOptionToMnemonic(
      MagickColorspaceOptions,(ssize_t) image->colorspace),MaxTextExtent);
    LocaleLower(colorspace);
    image->depth=GetImageQuantumDepth(image,MagickTrue);
    if (image->alpha_trait == BlendPixelTrait)
      (void) ConcatenateMagickString(colorspace,"a",MaxTextExtent);
    (void) FormatLocaleString(buffer,MaxTextExtent,
      "# ImageMagick pixel debugging: %.20g,%.20g,%.20g,%s\n",(double)
      image->columns,(double) image->rows,(double) ((MagickOffsetType)
      GetQuantumRange(image->depth)),colorspace);
    (void) WriteBlobString(image,buffer);
    GetPixelInfo(image,&pixel);
    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; x++)
      {
        (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g,%.20g: ",(double)
          x,(double) y);
        (void) WriteBlobString(image,buffer);
        GetPixelInfoPixel(image,p,&pixel);
        (void) FormatLocaleString(tuple,MaxTextExtent,"%.20g,%.20g,%.20g ",
          (double) pixel.red,(double) pixel.green,(double) pixel.blue);
        if (pixel.colorspace == CMYKColorspace)
          {
            char
              black[MaxTextExtent];

            (void) FormatLocaleString(black,MaxTextExtent,",%.20g ",
              (double) pixel.black);
            (void) ConcatenateMagickString(tuple,black,MaxTextExtent);
          }
        if (pixel.alpha_trait == BlendPixelTrait)
          {
            char
              alpha[MaxTextExtent];

            (void) FormatLocaleString(alpha,MaxTextExtent,",%.20g ",
              (double) pixel.alpha);
            (void) ConcatenateMagickString(tuple,alpha,MaxTextExtent);
          }
        (void) WriteBlobString(image,tuple);
        (void) WriteBlobString(image,"\n");
        p+=GetPixelChannels(image);
      }
      status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
        image->rows);
      if (status == MagickFalse)
        break;
    }
    if (GetNextImageInList(image) == (Image *) NULL)
      break;
    image=SyncNextImageInList(image);
    status=SetImageProgress(image,SaveImagesTag,scene++,
      GetImageListLength(image));
    if (status == MagickFalse)
      break;
  } while (image_info->adjoin != MagickFalse);
  (void) CloseBlob(image);
  return(MagickTrue);
}
Ejemplo n.º 16
0
static MagickBooleanType WriteCINImage(const ImageInfo *image_info,Image *image,
                                       ExceptionInfo *exception)
{
    const char
    *value;

    CINInfo
    cin;

    const StringInfo
    *profile;

    MagickBooleanType
    status;

    MagickOffsetType
    offset;

    QuantumInfo
    *quantum_info;

    QuantumType
    quantum_type;

    register const Quantum
    *p;

    register ssize_t
    i;

    size_t
    length;

    ssize_t
    count,
    y;

    struct tm
        local_time;

    time_t
    seconds;

    unsigned char
    *pixels;

    /*
      Open output image file.
    */
    assert(image_info != (const ImageInfo *) NULL);
    assert(image_info->signature == MagickSignature);
    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);
    status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
    if (status == MagickFalse)
        return(status);
    if (image->colorspace != LogColorspace)
        (void) TransformImageColorspace(image,LogColorspace,exception);
    /*
      Write image information.
    */
    (void) ResetMagickMemory(&cin,0,sizeof(cin));
    offset=0;
    cin.file.magic=0x802A5FD7UL;
    offset+=WriteBlobLong(image,(unsigned int) cin.file.magic);
    cin.file.image_offset=0x800;
    offset+=WriteBlobLong(image,(unsigned int) cin.file.image_offset);
    cin.file.generic_length=0x400;
    offset+=WriteBlobLong(image,(unsigned int) cin.file.generic_length);
    cin.file.industry_length=0x400;
    offset+=WriteBlobLong(image,(unsigned int) cin.file.industry_length);
    cin.file.user_length=0x00;
    profile=GetImageProfile(image,"dpx:user.data");
    if (profile != (StringInfo *) NULL)
    {
        cin.file.user_length+=(size_t) GetStringInfoLength(profile);
        cin.file.user_length=(((cin.file.user_length+0x2000-1)/0x2000)*0x2000);
    }
    offset+=WriteBlobLong(image,(unsigned int) cin.file.user_length);
    cin.file.file_size=4*image->columns*image->rows+0x2000;
    offset+=WriteBlobLong(image,(unsigned int) cin.file.file_size);
    (void) CopyMagickString(cin.file.version,"V4.5",sizeof(cin.file.version));
    offset+=WriteBlob(image,sizeof(cin.file.version),(unsigned char *)
                      cin.file.version);
    value=GetCINProperty(image_info,image,"dpx:file.filename",exception);
    if (value != (const char *) NULL)
        (void) CopyMagickString(cin.file.filename,value,sizeof(cin.file.filename));
    else
        (void) CopyMagickString(cin.file.filename,image->filename,
                                sizeof(cin.file.filename));
    offset+=WriteBlob(image,sizeof(cin.file.filename),(unsigned char *)
                      cin.file.filename);
    seconds=time((time_t *) NULL);
#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
    (void) localtime_r(&seconds,&local_time);
#else
    (void) memcpy(&local_time,localtime(&seconds),sizeof(local_time));
#endif
    (void) strftime(cin.file.create_date,sizeof(cin.file.create_date),"%Y:%m:%d",
                    &local_time);
    offset+=WriteBlob(image,sizeof(cin.file.create_date),(unsigned char *)
                      cin.file.create_date);
    (void) strftime(cin.file.create_time,sizeof(cin.file.create_time),
                    "%H:%M:%S%Z",&local_time);
    offset+=WriteBlob(image,sizeof(cin.file.create_time),(unsigned char *)
                      cin.file.create_time);
    offset+=WriteBlob(image,sizeof(cin.file.reserve),(unsigned char *)
                      cin.file.reserve);
    cin.image.orientation=0x00;
    offset+=WriteBlobByte(image,cin.image.orientation);
    cin.image.number_channels=3;
    offset+=WriteBlobByte(image,cin.image.number_channels);
    offset+=WriteBlob(image,sizeof(cin.image.reserve1),(unsigned char *)
                      cin.image.reserve1);
    for (i=0; i < 8; i++)
    {
        cin.image.channel[i].designator[0]=0; /* universal metric */
        offset+=WriteBlobByte(image,cin.image.channel[0].designator[0]);
        cin.image.channel[i].designator[1]=(unsigned char) (i > 3 ? 0 : i+1); /* channel color */;
        offset+=WriteBlobByte(image,cin.image.channel[1].designator[0]);
        cin.image.channel[i].bits_per_pixel=(unsigned char) image->depth;
        offset+=WriteBlobByte(image,cin.image.channel[0].bits_per_pixel);
        offset+=WriteBlobByte(image,cin.image.channel[0].reserve);
        cin.image.channel[i].pixels_per_line=image->columns;
        offset+=WriteBlobLong(image,(unsigned int)
                              cin.image.channel[0].pixels_per_line);
        cin.image.channel[i].lines_per_image=image->rows;
        offset+=WriteBlobLong(image,(unsigned int)
                              cin.image.channel[0].lines_per_image);
        cin.image.channel[i].min_data=0;
        offset+=WriteBlobFloat(image,cin.image.channel[0].min_data);
        cin.image.channel[i].min_quantity=0.0;
        offset+=WriteBlobFloat(image,cin.image.channel[0].min_quantity);
        cin.image.channel[i].max_data=(float) ((MagickOffsetType)
                                               GetQuantumRange(image->depth));
        offset+=WriteBlobFloat(image,cin.image.channel[0].max_data);
        cin.image.channel[i].max_quantity=2.048f;
        offset+=WriteBlobFloat(image,cin.image.channel[0].max_quantity);
    }
    offset+=WriteBlobFloat(image,image->chromaticity.white_point.x);
    offset+=WriteBlobFloat(image,image->chromaticity.white_point.y);
    offset+=WriteBlobFloat(image,image->chromaticity.red_primary.x);
    offset+=WriteBlobFloat(image,image->chromaticity.red_primary.y);
    offset+=WriteBlobFloat(image,image->chromaticity.green_primary.x);
    offset+=WriteBlobFloat(image,image->chromaticity.green_primary.y);
    offset+=WriteBlobFloat(image,image->chromaticity.blue_primary.x);
    offset+=WriteBlobFloat(image,image->chromaticity.blue_primary.y);
    value=GetCINProperty(image_info,image,"dpx:image.label",exception);
    if (value != (const char *) NULL)
        (void) CopyMagickString(cin.image.label,value,sizeof(cin.image.label));
    offset+=WriteBlob(image,sizeof(cin.image.label),(unsigned char *)
                      cin.image.label);
    offset+=WriteBlob(image,sizeof(cin.image.reserve),(unsigned char *)
                      cin.image.reserve);
    /*
      Write data format information.
    */
    cin.data_format.interleave=0; /* pixel interleave (rgbrgbr...) */
    offset+=WriteBlobByte(image,cin.data_format.interleave);
    cin.data_format.packing=5; /* packing ssize_tword (32bit) boundaries */
    offset+=WriteBlobByte(image,cin.data_format.packing);
    cin.data_format.sign=0; /* unsigned data */
    offset+=WriteBlobByte(image,cin.data_format.sign);
    cin.data_format.sense=0; /* image sense: positive image */
    offset+=WriteBlobByte(image,cin.data_format.sense);
    cin.data_format.line_pad=0;
    offset+=WriteBlobLong(image,(unsigned int) cin.data_format.line_pad);
    cin.data_format.channel_pad=0;
    offset+=WriteBlobLong(image,(unsigned int) cin.data_format.channel_pad);
    offset+=WriteBlob(image,sizeof(cin.data_format.reserve),(unsigned char *)
                      cin.data_format.reserve);
    /*
      Write origination information.
    */
    cin.origination.x_offset=0UL;
    value=GetCINProperty(image_info,image,"dpx:origination.x_offset",exception);
    if (value != (const char *) NULL)
        cin.origination.x_offset=(ssize_t) StringToLong(value);
    offset+=WriteBlobLong(image,(unsigned int) cin.origination.x_offset);
    cin.origination.y_offset=0UL;
    value=GetCINProperty(image_info,image,"dpx:origination.y_offset",exception);
    if (value != (const char *) NULL)
        cin.origination.y_offset=(ssize_t) StringToLong(value);
    offset+=WriteBlobLong(image,(unsigned int) cin.origination.y_offset);
    value=GetCINProperty(image_info,image,"dpx:origination.filename",exception);
    if (value != (const char *) NULL)
        (void) CopyMagickString(cin.origination.filename,value,
                                sizeof(cin.origination.filename));
    else
        (void) CopyMagickString(cin.origination.filename,image->filename,
                                sizeof(cin.origination.filename));
    offset+=WriteBlob(image,sizeof(cin.origination.filename),(unsigned char *)
                      cin.origination.filename);
    seconds=time((time_t *) NULL);
    (void) strftime(cin.origination.create_date,
                    sizeof(cin.origination.create_date),"%Y:%m:%d",&local_time);
    offset+=WriteBlob(image,sizeof(cin.origination.create_date),(unsigned char *)
                      cin.origination.create_date);
    (void) strftime(cin.origination.create_time,
                    sizeof(cin.origination.create_time),"%H:%M:%S%Z",&local_time);
    offset+=WriteBlob(image,sizeof(cin.origination.create_time),(unsigned char *)
                      cin.origination.create_time);
    value=GetCINProperty(image_info,image,"dpx:origination.device",exception);
    if (value != (const char *) NULL)
        (void) CopyMagickString(cin.origination.device,value,
                                sizeof(cin.origination.device));
    offset+=WriteBlob(image,sizeof(cin.origination.device),(unsigned char *)
                      cin.origination.device);
    value=GetCINProperty(image_info,image,"dpx:origination.model",exception);
    if (value != (const char *) NULL)
        (void) CopyMagickString(cin.origination.model,value,
                                sizeof(cin.origination.model));
    offset+=WriteBlob(image,sizeof(cin.origination.model),(unsigned char *)
                      cin.origination.model);
    value=GetCINProperty(image_info,image,"dpx:origination.serial",exception);
    if (value != (const char *) NULL)
        (void) CopyMagickString(cin.origination.serial,value,
                                sizeof(cin.origination.serial));
    offset+=WriteBlob(image,sizeof(cin.origination.serial),(unsigned char *)
                      cin.origination.serial);
    cin.origination.x_pitch=0.0f;
    value=GetCINProperty(image_info,image,"dpx:origination.x_pitch",exception);
    if (value != (const char *) NULL)
        cin.origination.x_pitch=StringToDouble(value,(char **) NULL);
    offset+=WriteBlobFloat(image,cin.origination.x_pitch);
    cin.origination.y_pitch=0.0f;
    value=GetCINProperty(image_info,image,"dpx:origination.y_pitch",exception);
    if (value != (const char *) NULL)
        cin.origination.y_pitch=StringToDouble(value,(char **) NULL);
    offset+=WriteBlobFloat(image,cin.origination.y_pitch);
    cin.origination.gamma=image->gamma;
    offset+=WriteBlobFloat(image,cin.origination.gamma);
    offset+=WriteBlob(image,sizeof(cin.origination.reserve),(unsigned char *)
                      cin.origination.reserve);
    /*
      Image film information.
    */
    cin.film.id=0;
    value=GetCINProperty(image_info,image,"dpx:film.id",exception);
    if (value != (const char *) NULL)
        cin.film.id=(char) StringToLong(value);
    offset+=WriteBlobByte(image,(unsigned char) cin.film.id);
    cin.film.type=0;
    value=GetCINProperty(image_info,image,"dpx:film.type",exception);
    if (value != (const char *) NULL)
        cin.film.type=(char) StringToLong(value);
    offset+=WriteBlobByte(image,(unsigned char) cin.film.type);
    cin.film.offset=0;
    value=GetCINProperty(image_info,image,"dpx:film.offset",exception);
    if (value != (const char *) NULL)
        cin.film.offset=(char) StringToLong(value);
    offset+=WriteBlobByte(image,(unsigned char) cin.film.offset);
    offset+=WriteBlobByte(image,(unsigned char) cin.film.reserve1);
    cin.film.prefix=0UL;
    value=GetCINProperty(image_info,image,"dpx:film.prefix",exception);
    if (value != (const char *) NULL)
        cin.film.prefix=StringToUnsignedLong(value);
    offset+=WriteBlobLong(image,(unsigned int) cin.film.prefix);
    cin.film.count=0UL;
    value=GetCINProperty(image_info,image,"dpx:film.count",exception);
    if (value != (const char *) NULL)
        cin.film.count=StringToUnsignedLong(value);
    offset+=WriteBlobLong(image,(unsigned int) cin.film.count);
    value=GetCINProperty(image_info,image,"dpx:film.format",exception);
    if (value != (const char *) NULL)
        (void) CopyMagickString(cin.film.format,value,sizeof(cin.film.format));
    offset+=WriteBlob(image,sizeof(cin.film.format),(unsigned char *)
                      cin.film.format);
    cin.film.frame_position=0UL;
    value=GetCINProperty(image_info,image,"dpx:film.frame_position",exception);
    if (value != (const char *) NULL)
        cin.film.frame_position=StringToUnsignedLong(value);
    offset+=WriteBlobLong(image,(unsigned int) cin.film.frame_position);
    cin.film.frame_rate=0.0f;
    value=GetCINProperty(image_info,image,"dpx:film.frame_rate",exception);
    if (value != (const char *) NULL)
        cin.film.frame_rate=StringToDouble(value,(char **) NULL);
    offset+=WriteBlobFloat(image,cin.film.frame_rate);
    value=GetCINProperty(image_info,image,"dpx:film.frame_id",exception);
    if (value != (const char *) NULL)
        (void) CopyMagickString(cin.film.frame_id,value,sizeof(cin.film.frame_id));
    offset+=WriteBlob(image,sizeof(cin.film.frame_id),(unsigned char *)
                      cin.film.frame_id);
    value=GetCINProperty(image_info,image,"dpx:film.slate_info",exception);
    if (value != (const char *) NULL)
        (void) CopyMagickString(cin.film.slate_info,value,
                                sizeof(cin.film.slate_info));
    offset+=WriteBlob(image,sizeof(cin.film.slate_info),(unsigned char *)
                      cin.film.slate_info);
    offset+=WriteBlob(image,sizeof(cin.film.reserve),(unsigned char *)
                      cin.film.reserve);
    if (profile != (StringInfo *) NULL)
        offset+=WriteBlob(image,GetStringInfoLength(profile),
                          GetStringInfoDatum(profile));
    while (offset < (MagickOffsetType) cin.file.image_offset)
        offset+=WriteBlobByte(image,0x00);
    /*
      Convert pixel packets to CIN raster image.
    */
    quantum_info=AcquireQuantumInfo(image_info,image);
    if (quantum_info == (QuantumInfo *) NULL)
        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
    quantum_info->quantum=32;
    quantum_info->pack=MagickFalse;
    quantum_type=RGBQuantum;
    pixels=GetQuantumPixels(quantum_info);
    length=GetBytesPerRow(image->columns,3,image->depth,MagickTrue);
    if (0)
    {
        quantum_type=GrayQuantum;
        length=GetBytesPerRow(image->columns,1,image->depth,MagickTrue);
    }
    for (y=0; y < (ssize_t) image->rows; y++)
    {
        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
        if (p == (const Quantum *) NULL)
            break;
        (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
                                   quantum_type,pixels,exception);
        count=WriteBlob(image,length,pixels);
        if (count != (ssize_t) length)
            break;
        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
                                image->rows);
        if (status == MagickFalse)
            break;
    }
    quantum_info=DestroyQuantumInfo(quantum_info);
    (void) CloseBlob(image);
    return(status);
}
Ejemplo n.º 17
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=GetOpenMPMaximumThreads();
  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->matte == MagickFalse))
    {
      register const PixelInfo
        *restrict p;

      register ssize_t
        i;

      p=image->colormap;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(static,4) shared(status)
#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|=p->red != ScaleAnyToQuantum(ScaleQuantumToAny(p->red,
              range),range);
          if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
            status|=p->green != ScaleAnyToQuantum(ScaleQuantumToAny(p->green,
              range),range);
          if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
            status|=p->blue != ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,
              range),range);
          if (status == 0)
            break;
          current_depth[id]++;
        }
        p++;
      }
      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=AcquireCacheView(image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(static,4) shared(status)
#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;

      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
      {
        PixelChannel
          channel;

        PixelTrait
          traits;

        channel=GetPixelChannelMapChannel(image,i);
        traits=GetPixelChannelMapTraits(image,channel);
        if (traits == UndefinedPixelTrait)
          continue;
        while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
        {
          MagickStatusType
            status;

          QuantumAny
            range;

          status=0;
          range=GetQuantumRange(current_depth[id]);
          status|=p[i] != ScaleAnyToQuantum(ScaleQuantumToAny(p[i],range),
            range);
          if (status == 0)
            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);
}
Ejemplo n.º 18
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e T X T I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteTXTImage writes the pixel values as text numbers.
%
%  The format of the WriteTXTImage method is:
%
%      MagickBooleanType WriteTXTImage(const ImageInfo *image_info,Image *image)
%
%  A description of each parameter follows.
%
%    o image_info: the image info.
%
%    o image:  The image.
%
*/
static MagickBooleanType WriteTXTImage(const ImageInfo *image_info,Image *image)
{
  char
    buffer[MaxTextExtent],
    colorspace[MaxTextExtent],
    tuple[MaxTextExtent];

  MagickBooleanType
    status;

  MagickOffsetType
    scene;

  MagickPixelPacket
    pixel;

  register const IndexPacket
    *indexes;

  register const PixelPacket
    *p;

  register ssize_t
    x;

  ssize_t
    y;

  /*
    Open output image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  status=OpenBlob(image_info,image,WriteBlobMode,&image->exception);
  if (status == MagickFalse)
    return(status);
  scene=0;
  do
  {
    ComplianceType
      compliance;

    (void) CopyMagickString(colorspace,CommandOptionToMnemonic(
      MagickColorspaceOptions,(ssize_t) image->colorspace),MaxTextExtent);
    LocaleLower(colorspace);
    image->depth=GetImageQuantumDepth(image,MagickTrue);
    if (image->matte != MagickFalse)
      (void) ConcatenateMagickString(colorspace,"a",MaxTextExtent);
    compliance=NoCompliance;
    if (LocaleCompare(image_info->magick,"SPARSE-COLOR") != 0)
      {
        (void) FormatLocaleString(buffer,MaxTextExtent,
          "# ImageMagick pixel enumeration: %.20g,%.20g,%.20g,%s\n",(double)
          image->columns,(double) image->rows,(double) ((MagickOffsetType)
          GetQuantumRange(image->depth)),colorspace);
        (void) WriteBlobString(image,buffer);
        compliance=SVGCompliance;
      }
    GetMagickPixelPacket(image,&pixel);
    for (y=0; y < (ssize_t) image->rows; y++)
    {
      p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
      if (p == (const PixelPacket *) NULL)
        break;
      indexes=GetVirtualIndexQueue(image);
      for (x=0; x < (ssize_t) image->columns; x++)
      {
        SetMagickPixelPacket(image,p,indexes+x,&pixel);
        if (pixel.colorspace == LabColorspace)
          {
            pixel.green-=(QuantumRange+1)/2.0;
            pixel.blue-=(QuantumRange+1)/2.0;
          }
        if (LocaleCompare(image_info->magick,"SPARSE-COLOR") == 0)
          {
            /*
              Sparse-color format.
            */
            if (GetPixelOpacity(p) == (Quantum) OpaqueOpacity)
              {
                GetColorTuple(&pixel,MagickFalse,tuple);
                (void) QueryMagickColorname(image,&pixel,SVGCompliance,tuple,
                  &image->exception);
                (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g,%.20g,",
                  (double) x,(double) y);
                (void) WriteBlobString(image,buffer);
                (void) WriteBlobString(image,tuple);
                (void) WriteBlobString(image," ");
              }
            p++;
            continue;
          }
        (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g,%.20g: ",(double)
          x,(double) y);
        (void) WriteBlobString(image,buffer);
        (void) CopyMagickString(tuple,"(",MaxTextExtent);
        ConcatenateColorComponent(&pixel,RedChannel,compliance,tuple);
        (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
        ConcatenateColorComponent(&pixel,GreenChannel,compliance,tuple);
        (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
        ConcatenateColorComponent(&pixel,BlueChannel,compliance,tuple);
        if (pixel.colorspace == CMYKColorspace)
          {
            (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
            ConcatenateColorComponent(&pixel,IndexChannel,compliance,tuple);
          }
        if (pixel.matte != MagickFalse)
          {
            (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
            ConcatenateColorComponent(&pixel,AlphaChannel,compliance,tuple);
          }
        (void) ConcatenateMagickString(tuple,")",MaxTextExtent);
        (void) WriteBlobString(image,tuple);
        (void) WriteBlobString(image,"  ");
        GetColorTuple(&pixel,MagickTrue,tuple);
        (void) FormatLocaleString(buffer,MaxTextExtent,"%s",tuple);
        (void) WriteBlobString(image,buffer);
        (void) WriteBlobString(image,"  ");
        (void) QueryMagickColorname(image,&pixel,SVGCompliance,tuple,
          &image->exception);
        (void) WriteBlobString(image,tuple);
        (void) WriteBlobString(image,"\n");
        p++;
      }
      status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
        image->rows);
      if (status == MagickFalse)
        break;
    }
    if (GetNextImageInList(image) == (Image *) NULL)
      break;
    image=SyncNextImageInList(image);
    status=SetImageProgress(image,SaveImagesTag,scene++,
      GetImageListLength(image));
    if (status == MagickFalse)
      break;
  } while (image_info->adjoin != MagickFalse);
  (void) CloseBlob(image);
  return(MagickTrue);
}
Ejemplo n.º 19
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 (GetImageDepth(image,exception) <= (size_t)
      MagickMin((double) depth,(double) MAGICKCORE_QUANTUM_DEPTH))
    {
      image->depth=depth;
      return(MagickTrue);
    }
  /*
    Scale pixels to desired depth.
  */
  status=MagickTrue;
  range=GetQuantumRange(depth);
  image_view=AcquireCacheView(image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(static,4) shared(status)
#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;

      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
      {
        PixelChannel
          channel;

        PixelTrait
          traits;

        channel=GetPixelChannelMapChannel(image,i);
        traits=GetPixelChannelMapTraits(image,channel);
        if (traits == UndefinedPixelTrait)
          continue;
        q[i]=ScaleAnyToQuantum(ScaleQuantumToAny(q[i],range),range);
      }
      q+=GetPixelChannels(image);
    }
    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
      {
        status=MagickFalse;
        continue;
      }
  }
  image_view=DestroyCacheView(image_view);
  if (image->storage_class == PseudoClass)
    {
      register PixelInfo
        *restrict p;

      register ssize_t
        i;

      p=image->colormap;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(static,4) shared(status)
#endif
      for (i=0; i < (ssize_t) image->colors; i++)
      {
        if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
          p->red=ScaleAnyToQuantum(ScaleQuantumToAny(p->red,range),range);
        if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
          p->green=ScaleAnyToQuantum(ScaleQuantumToAny(p->green,range),range);
        if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
          p->blue=ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,range),range);
        if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
          p->alpha=ScaleAnyToQuantum(ScaleQuantumToAny(p->alpha,range),range);
        p++;
      }
    }
  image->depth=depth;
  return(status);
}
Ejemplo n.º 20
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);
    }
Ejemplo n.º 21
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d T X T I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadTXTImage() reads a text file and returns it as an image.  It allocates
%  the memory necessary for the new Image structure and returns a pointer to
%  the new image.
%
%  The format of the ReadTXTImage method is:
%
%      Image *ReadTXTImage(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 *ReadTXTImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  char
    colorspace[MaxTextExtent],
    text[MaxTextExtent];

  Image
    *image;

  IndexPacket
    *indexes;

  long
    type,
    x,
    y;

  LongPixelPacket
    pixel;

  MagickBooleanType
    status;

  QuantumAny
    range;

  register long
    i;

  register PixelPacket
    *q;

  ssize_t
    count;

  unsigned long
    depth,
    max_value;

  /*
    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);
    }
  (void) ResetMagickMemory(text,0,sizeof(text));
  (void) ReadBlobString(image,text);
  if (LocaleNCompare((char *) text,MagickID,strlen(MagickID)) != 0)
    return(ReadTEXTImage(image_info,image,text,exception));
  *colorspace='\0';
  count=(ssize_t) sscanf(text+32,"%lu,%lu,%lu,%s",&image->columns,
    &image->rows,&max_value,colorspace);
  if (count != 4)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  for (depth=1; (GetQuantumRange(depth)+1) < max_value; depth++) ;
  image->depth=depth;
  LocaleLower(colorspace);
  i=(long) strlen(colorspace)-1;
  image->matte=MagickFalse;
  if ((i > 0) && (colorspace[i] == 'a'))
    {
      colorspace[i]='\0';
      image->matte=MagickTrue;
    }
  type=ParseMagickOption(MagickColorspaceOptions,MagickFalse,colorspace);
  if (type < 0)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  image->colorspace=(ColorspaceType) type;
  (void) ResetMagickMemory(&pixel,0,sizeof(pixel));
  (void) SetImageBackgroundColor(image);
  range=GetQuantumRange(image->depth);
  while (ReadBlobString(image,text) != (char *) NULL)
  {
    if (image->colorspace == CMYKColorspace)
      {
        if (image->matte != MagickFalse)
          count=(ssize_t) sscanf(text,"%ld,%ld: (%lu,%lu,%lu,%lu,%lu",&x,&y,
            &pixel.red,&pixel.green,&pixel.blue,&pixel.index,&pixel.opacity);
        else
          count=(ssize_t) sscanf(text,"%ld,%ld: (%lu,%lu,%lu,%lu",&x,&y,
            &pixel.red,&pixel.green,&pixel.blue,&pixel.index);
      }
    else
      if (image->matte != MagickFalse)
        count=(ssize_t) sscanf(text,"%ld,%ld: (%lu,%lu,%lu,%lu",&x,&y,
          &pixel.red,&pixel.green,&pixel.blue,&pixel.opacity);
      else
        count=(ssize_t) sscanf(text,"%ld,%ld: (%lu,%lu,%lu",&x,&y,
          &pixel.red,&pixel.green,&pixel.blue);
    if (count < 5)
      continue;
    q=GetAuthenticPixels(image,x,y,1,1,exception);
    if (q == (PixelPacket *) NULL)
      continue;
    q->red=ScaleAnyToQuantum(pixel.red,range);
    q->green=ScaleAnyToQuantum(pixel.green,range);
    q->blue=ScaleAnyToQuantum(pixel.blue,range);
    if (image->colorspace == CMYKColorspace)
      {
        indexes=GetAuthenticIndexQueue(image);
        *indexes=ScaleAnyToQuantum(pixel.index,range);
      }
    if (image->matte != MagickFalse)
      q->opacity=(Quantum) (QuantumRange-ScaleAnyToQuantum(pixel.opacity,
        range));
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
  }
  return(GetFirstImageInList(image));
}