Ejemplo n.º 1
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e M G K I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteMGKImage() writes an image to a file in red, green, and blue
%  MGK rasterfile format.
%
%  The format of the WriteMGKImage method is:
%
%      MagickBooleanType WriteMGKImage(const ImageInfo *image_info,
%        Image *image)
%
%  A description of each parameter follows.
%
%    o image_info: the image info.
%
%    o image:  The image.
%
*/
static MagickBooleanType WriteMGKImage(const ImageInfo *image_info,
  Image *image)
{
  char
    buffer[MaxTextExtent];

  MagickBooleanType
    status;

  MagickOffsetType
    scene;

  register const PixelPacket
    *p;

  register ssize_t
    x;

  register unsigned char
    *q;

  ssize_t
    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);
  scene=0;
  do
  {
    /*
      Allocate memory for pixels.
    */
    if (image->colorspace != RGBColorspace)
      (void) SetImageColorspace(image,RGBColorspace);
    pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->columns,
      3UL*sizeof(*pixels));
    if (pixels == (unsigned char *) NULL)
      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
    /*
      Initialize raster file header.
    */
    (void) WriteBlobString(image,"id=mgk\n");
    (void) FormatMagickString(buffer,MaxTextExtent,"%lu %lu\n",image->columns,
      image->rows);
    (void) WriteBlobString(image,buffer);
    for (y=0; y < (ssize_t) image->rows; y++)
    {
      p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
      if (p == (const PixelPacket *) NULL)
        break;
      q=pixels;
      for (x=0; x < (ssize_t) image->columns; x++)
      {
        *q++=ScaleQuantumToChar(GetRedSample(p));
        *q++=ScaleQuantumToChar(GetGreenSample(p));
        *q++=ScaleQuantumToChar(GetBlueSample(p));
        p++;
      }
      (void) WriteBlob(image,(size_t) (q-pixels),pixels);
      if ((image->previous == (Image *) NULL) &&
          (SetImageProgress(image,SaveImageTag,y,image->rows) == MagickFalse))
        break;
    }
    pixels=(unsigned char *) RelinquishMagickMemory(pixels);
    if (GetNextImageInList(image) == (Image *) NULL)
      break;
    image=SyncNextImageInList(image);
    status=SetImageProgress(image,SaveImagesTag,scene,
      GetImageListLength(image));
    if (status == MagickFalse)
      break;
    scene++;
  } while (image_info->adjoin != MagickFalse);
  (void) CloseBlob(image);
  return(MagickTrue);
}
Ejemplo n.º 2
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   D i f f e r e n c e I m a g e                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  DifferenceImage() returns an annotated difference image based on the
%  the difference between a reference image and a compare image.
%
%  The format of the DifferenceImage method is:
%
%      Image *DifferenceImage(const Image *reference_image,
%                             const Image *compare_image,
%                             const DifferenceImageOptions *difference_options,
%                             ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o reference_image: the reference image.
%
%    o compare_image: the comparison image.
%
%    o difference_options: options to use when differencing.
%
%    o channel: the channel(s) to compare.
%
%    o exception: Return any errors or warnings in this structure.
%
*/
static MagickPassFail
DifferenceImagePixels(void *mutable_data,                  /* User provided mutable data */
                      const void *immutable_data,          /* User provided immutable data */
                      const Image *reference_image,        /* Source 1 image */
                      const PixelPacket *reference_pixels, /* Pixel row in source 1 image */
                      const IndexPacket *reference_indexes,/* Pixel row indexes in source 1 image */
                      const Image *compare_image,          /* Source 2 image */
                      const PixelPacket *compare_pixels,   /* Pixel row in source 2 image */
                      const IndexPacket *compare_indexes,  /* Pixel row indexes in source 2 image */
                      Image *result_image,                 /* Update image */
                      PixelPacket *result_pixels,          /* Pixel row in update image */
                      IndexPacket *result_indexes,         /* Pixel row indexes in update image */
                      const long npixels,                  /* Number of pixels in row */
                      ExceptionInfo *exception             /* Exception report */
                   )
{
  const DifferenceImageOptions
    *difference_options = (const DifferenceImageOptions *) immutable_data;

  register ChannelType
    channels = difference_options->channel;

  register long
    i;

  register MagickBool
    change;

  ARG_NOT_USED(mutable_data);
  ARG_NOT_USED(compare_image);
  ARG_NOT_USED(result_image);
  ARG_NOT_USED(result_indexes);
  ARG_NOT_USED(exception);

  for (i=0; i < npixels; i++)
    {
      change=MagickFalse;

      if (IsCMYKColorspace(reference_image->colorspace))
        {
          if (MagickChannelEnabled(channels,CyanChannel) &&
              (GetCyanSample(&reference_pixels[i]) != GetCyanSample(&compare_pixels[i])))
            change=MagickTrue;
          if (MagickChannelEnabled(channels,MagentaChannel) &&
              (GetMagentaSample(&reference_pixels[i]) != GetMagentaSample(&compare_pixels[i])))
            change=MagickTrue;
          if (MagickChannelEnabled(channels,YellowChannel) &&
              (GetYellowSample(&reference_pixels[i]) != GetYellowSample(&compare_pixels[i])))
            change=MagickTrue;
          if (MagickChannelEnabled(channels,BlackChannel) &&
              (GetBlackSample(&reference_pixels[i]) != GetBlackSample(&compare_pixels[i])))
            change=MagickTrue;
          if (MagickChannelEnabled(channels,OpacityChannel) &&
              (reference_indexes[i] != compare_indexes[i]))
            change=MagickTrue;
        }
      else
        {
          if (MagickChannelEnabled(channels,RedChannel) &&
              (GetRedSample(&reference_pixels[i]) != GetRedSample(&compare_pixels[i])))
            change=MagickTrue;
          if (MagickChannelEnabled(channels,GreenChannel) &&
              (GetGreenSample(&reference_pixels[i]) != GetGreenSample(&compare_pixels[i])))
            change=MagickTrue;
          if (MagickChannelEnabled(channels,BlueChannel) &&
              (GetBlueSample(&reference_pixels[i]) != GetBlueSample(&compare_pixels[i])))
            change=MagickTrue;
          if (MagickChannelEnabled(channels,OpacityChannel) &&
              (GetOpacitySample(&reference_pixels[i]) != GetOpacitySample(&compare_pixels[i])))
            change=MagickTrue;
        }
      /*
        Modify result image to reflect change.
      */
      switch (difference_options->highlight_style)
        {
        case UndefinedHighlightStyle:
          break;
        case AssignHighlightStyle:
          {
            /*
              Changed pixels are assigned the highlight color.
            */
            if (change)
              result_pixels[i]=difference_options->highlight_color;
            else
              result_pixels[i]=compare_pixels[i];
            break;
          }
        case ThresholdHighlightStyle:
          {
            /*
              For changed pixels, compare the pixel intensity.  If the
              pixel intensity in the compare image is higher than the
              reference image, then set the pixel to white, otherwise
              set it to black.
            */
            if (change)
              {
                Quantum
                  compare_intensity,
                  intensity,
                  reference_intensity;

                compare_intensity=PixelIntensity(&compare_pixels[i]);
                reference_intensity=PixelIntensity(&reference_pixels[i]);
                if (compare_intensity > reference_intensity)
                  intensity=MaxRGB;
                else
                  intensity=0U;
                result_pixels[i].red = result_pixels[i].green = result_pixels[i].blue = intensity;
                result_pixels[i].opacity=compare_pixels[i].opacity;
              }
            else
              {
                result_pixels[i]=compare_pixels[i];
              }
            break;
          }
        case TintHighlightStyle:
          {
            /*
              Alpha composite highlight color on top of change pixels.
            */
            if (change)
              AlphaCompositePixel(&result_pixels[i],&difference_options->highlight_color,0.75*MaxRGBDouble,
                                  &compare_pixels[i],compare_pixels[i].opacity);
            else
              result_pixels[i]=compare_pixels[i];
            break;
          }
        case XorHighlightStyle:
          {
            if (change)
              {
                result_pixels[i].red = compare_pixels[i].red ^ difference_options->highlight_color.red;
                result_pixels[i].green = compare_pixels[i].green ^ difference_options->highlight_color.green;
                result_pixels[i].blue = compare_pixels[i].blue ^ difference_options->highlight_color.blue;
                result_pixels[i].opacity = compare_pixels[i].opacity ^ difference_options->highlight_color.opacity;
              }
            else
              {
                result_pixels[i]=compare_pixels[i];
              }
            break;
          }
        }
    }

  return MagickPass;
}