Пример #1
0
Файл: yuv.c Проект: vgck/opendr2
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e Y U V I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method WriteYUVImage writes an image to a file in the digital YUV
%  (CCIR 601 4:1:1) format.
%
%  The format of the WriteYUVImage method is:
%
%      unsigned int WriteYUVImage(const ImageInfo *image_info,Image *image)
%
%  A description of each parameter follows.
%
%    o status: Method WriteYUVImage return True if the image is written.
%      False is returned is there is a memory shortage or if the image file
%      fails to write.
%
%    o image_info: Specifies a pointer to an ImageInfo structure.
%
%    o image:  A pointer to a Image structure.
%
%
*/
Export unsigned int WriteYUVImage(const ImageInfo *image_info,Image *image)
{
  Image
    *chroma_image,
    *yuv_image;

  int
    y;

  register int
    x;

  register PixelPacket
    *p;

  unsigned int
    height,
    scene,
    status,
    width;

  if (image_info->interlace != PartitionInterlace)
    {
      /*
        Open output image file.
      */
      status=OpenBlob(image_info,image,WriteBinaryType);
      if (status == False)
        WriterExit(FileOpenWarning,"Unable to open file",image);
    }
  if (image_info->interlace == PartitionInterlace)
    {
      AppendImageFormat("Y",image->filename);
      status=OpenBlob(image_info,image,WriteBinaryType);
      if (status == False)
        WriterExit(FileOpenWarning,"Unable to open file",image);
    }
  scene=0;
  do
  {
    /*
      Sample image to an even width and height.
    */
    TransformRGBImage(image,RGBColorspace);
    width=image->columns+(image->columns & 0x01);
    height=image->rows+(image->rows & 0x01);
    image->orphan=True;
    yuv_image=SampleImage(image,width,height);
    if (yuv_image == (Image *) NULL)
      WriterExit(ResourceLimitWarning,"Unable to zoom image",image);
    RGBTransformImage(yuv_image,YCbCrColorspace);
    /*
      Initialize Y channel.
    */
    for (y=0; y < (int) yuv_image->rows; y++)
    {
      p=GetPixelCache(yuv_image,0,y,yuv_image->columns,1);
      if (p == (PixelPacket *) NULL)
        break;
      for (x=0; x < (int) yuv_image->columns; x++)
      {
        (void) WriteByte(image,DownScale(p->red));
        p++;
      }
      if (image->previous == (Image *) NULL)
        if (QuantumTick(y,image->rows))
          ProgressMonitor(SaveImageText,y,image->rows);
    }
    DestroyImage(yuv_image);
    /*
      Downsample image.
    */
    image->orphan=True;
    chroma_image=SampleImage(image,width/2,height/2);
    if (chroma_image == (Image *) NULL)
      WriterExit(ResourceLimitWarning,"Unable to zoom image",image);
    RGBTransformImage(chroma_image,YCbCrColorspace);
    /*
      Initialize U channel.
    */
    if (image_info->interlace == PartitionInterlace)
      {
        CloseBlob(image);
        AppendImageFormat("U",image->filename);
        status=OpenBlob(image_info,image,WriteBinaryType);
        if (status == False)
          WriterExit(FileOpenWarning,"Unable to open file",image);
      }
    for (y=0; y < (int) chroma_image->rows; y++)
    {
      p=GetPixelCache(chroma_image,0,y,chroma_image->columns,1);
      if (p == (PixelPacket *) NULL)
        break;
      for (x=0; x < (int) chroma_image->columns; x++)
      {
        (void) WriteByte(image,DownScale(p->green));
        p++;
      }
    }
    /*
      Initialize V channel.
    */
    if (image_info->interlace == PartitionInterlace)
      {
        CloseBlob(image);
        AppendImageFormat("V",image->filename);
        status=OpenBlob(image_info,image,WriteBinaryType);
        if (status == False)
          WriterExit(FileOpenWarning,"Unable to open file",image);
      }
    for (y=0; y < (int) chroma_image->rows; y++)
    {
      p=GetPixelCache(chroma_image,0,y,chroma_image->columns,1);
      if (p == (PixelPacket *) NULL)
        break;
      for (x=0; x < (int) chroma_image->columns; x++)
      {
	(void) WriteByte(image,DownScale(p->blue));
        p++;
      }
    }
    DestroyImage(chroma_image);
    if (image_info->interlace == PartitionInterlace)
      (void) strcpy(image->filename,image_info->filename);
    if (image->next == (Image *) NULL)
      break;
    image=GetNextImage(image);
    ProgressMonitor(SaveImagesText,scene++,GetNumberScenes(image));
  } while (image_info->adjoin);
  if (image_info->adjoin)
    while (image->previous != (Image *) NULL)
      image=image->previous;
  CloseBlob(image);
  return(True);
}
Пример #2
0
Файл: yuv.c Проект: vgck/opendr2
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d Y U V I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method ReadYUVImage reads an image with digital YUV (CCIR 601 4:1:1) bytes
%  and returns it.  It allocates the memory necessary for the new Image
%  structure and returns a pointer to the new image.
%
%  The format of the ReadYUVImage method is:
%
%      Image *ReadYUVImage(const ImageInfo *image_info)
%
%  A description of each parameter follows:
%
%    o image:  Method ReadYUVImage returns a pointer to the image after
%      reading.  A null image is returned if there is a memory shortage or
%      if the image cannot be read.
%
%    o image_info: Specifies a pointer to an ImageInfo structure.
%
%
*/
Export Image *ReadYUVImage(const ImageInfo *image_info)
{
  Image
    *chroma_image,
    *image,
    *zoom_image;

  int
    count,
    y;

  register int
    i,
    x;

  register PixelPacket
    *q,
    *r;

  register unsigned char
    *p;

  unsigned char
    *scanline;

  unsigned int
    status;

  /*
    Allocate image structure.
  */
  image=AllocateImage(image_info);
  if (image == (Image *) NULL)
    return((Image *) NULL);
  if ((image->columns == 0) || (image->rows == 0))
    ReaderExit(OptionWarning,"Must specify image size",image);
  image->depth=8;
  if (image_info->interlace != PartitionInterlace)
    {
      /*
        Open image file.
      */
      status=OpenBlob(image_info,image,ReadBinaryType);
      if (status == False)
        ReaderExit(FileOpenWarning,"Unable to open file",image);
      for (i=0; i < image->offset; i++)
        (void) ReadByte(image);
    }
  /*
    Allocate memory for a scanline.
  */
  scanline=(unsigned char *)
    AllocateMemory(image->columns*sizeof(unsigned char));
  if (scanline == (unsigned char *) NULL)
    ReaderExit(ResourceLimitWarning,"Memory allocation failed",image);
  do
  {
    /*
      Convert raster image to pixel packets.
    */
    if (image_info->interlace == PartitionInterlace)
      {
        AppendImageFormat("Y",image->filename);
        status=OpenBlob(image_info,image,ReadBinaryType);
        if (status == False)
          ReaderExit(FileOpenWarning,"Unable to open file",image);
      }
    for (y=0; y < (int) image->rows; y++)
    {
      if ((y > 0) || (image->previous == (Image *) NULL))
        (void) ReadBlob(image,image->columns,scanline);
      p=scanline;
      q=SetPixelCache(image,0,y,image->columns,1);
      if (q == (PixelPacket *) NULL)
        break;
      for (x=0; x < (int) image->columns; x++)
      {
        q->red=UpScale(*p++);
        q->green=0;
        q->blue=0;
        q++;
      }
      if (!SyncPixelCache(image))
        break;
      if (image->previous == (Image *) NULL)
        ProgressMonitor(LoadImageText,y,image->rows);
    }
    if (image_info->interlace == PartitionInterlace)
      {
        CloseBlob(image);
        AppendImageFormat("U",image->filename);
        status=OpenBlob(image_info,image,ReadBinaryType);
        if (status == False)
          ReaderExit(FileOpenWarning,"Unable to open file",image);
      }
    chroma_image=CloneImage(image,image->columns/2,image->rows/2,True);
    if (chroma_image == (Image *) NULL)
      ReaderExit(ResourceLimitWarning,"Memory allocation failed",image);
    for (y=0; y < (int) chroma_image->rows; y++)
    {
      (void) ReadBlob(image,chroma_image->columns,scanline);
      p=scanline;
      q=SetPixelCache(chroma_image,0,y,chroma_image->columns,1);
      if (q == (PixelPacket *) NULL)
        break;
      for (x=0; x < (int) chroma_image->columns; x++)
      {
        q->red=0;
        q->green=UpScale(*p++);
        q->blue=0;
        q++;
      }
      if (!SyncPixelCache(chroma_image))
        break;
    }
    if (image_info->interlace == PartitionInterlace)
      {
        CloseBlob(image);
        AppendImageFormat("V",image->filename);
        status=OpenBlob(image_info,image,ReadBinaryType);
        if (status == False)
          ReaderExit(FileOpenWarning,"Unable to open file",image);
      }
    for (y=0; y < (int) chroma_image->rows; y++)
    {
      (void) ReadBlob(image,chroma_image->columns,scanline);
      p=scanline;
      q=GetPixelCache(chroma_image,0,y,chroma_image->columns,1);
      if (q == (PixelPacket *) NULL)
        break;
      for (x=0; x < (int) chroma_image->columns; x++)
      {
        q->blue=UpScale(*p++);
        q++;
      }
      if (!SyncPixelCache(chroma_image))
        break;
    }
    /*
      Scale image.
    */
    chroma_image->orphan=True;
    zoom_image=SampleImage(chroma_image,image->columns,image->rows);
    DestroyImage(chroma_image);
    if (zoom_image == (Image *) NULL)
      ReaderExit(ResourceLimitWarning,"Memory allocation failed",image);
    for (y=0; y < (int) image->rows; y++)
    {
      q=GetPixelCache(image,0,y,image->columns,1);
      r=GetPixelCache(zoom_image,0,y,zoom_image->columns,1);
      if ((q == (PixelPacket *) NULL) || (r == (PixelPacket *) NULL))
        break;
      for (x=0; x < (int) image->columns; x++)
      {
        q->green=r->green;
        q->blue=r->blue;
        r++;
        q++;
      }
      if (!SyncPixelCache(image))
        break;
    }
    DestroyImage(zoom_image);
    TransformRGBImage(image,YCbCrColorspace);
    if (image_info->interlace == PartitionInterlace)
      (void) strcpy(image->filename,image_info->filename);
    /*
      Proceed to next image.
    */
    if (image_info->subrange != 0)
      if (image->scene >= (image_info->subimage+image_info->subrange-1))
        break;
    count=ReadBlob(image,image->columns,(char *) scanline);
    if (count > 0)
      {
        /*
          Allocate next image structure.
        */
        AllocateNextImage(image_info,image);
        if (image->next == (Image *) NULL)
          {
            DestroyImages(image);
            return((Image *) NULL);
          }
        image=image->next;
        ProgressMonitor(LoadImagesText,TellBlob(image),image->filesize);
      }
  } while (count > 0);
  FreeMemory(scanline);
  while (image->previous != (Image *) NULL)
    image=image->previous;
  CloseBlob(image);
  return(image);
}
Пример #3
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%     N o r m a l i z e I m a g e                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method NormalizeImage normalizes the pixel values to span the full
%  range of color values.  This is a contrast enhancement technique.
%
%  The format of the NormalizeImage method is:
%
%      void NormalizeImage(Image *image)
%
%  A description of each parameter follows:
%
%    o image: The address of a structure of type Image;  returned from
%      ReadImage.
%
%
*/
Export void NormalizeImage(Image *image)
{
#define NormalizeImageText  "  Normalizing image...  "

  int
    *histogram,
    threshold_intensity,
    y;

  Quantum
    gray_value,
    *normalize_map;

  register int
    i,
    intensity,
    x;

  register PixelPacket
    *p,
    *q;

  unsigned int
    high,
    low;

  /*
    Allocate histogram and normalize map.
  */
  assert(image != (Image *) NULL);
  histogram=(int *) AllocateMemory((MaxRGB+1)*sizeof(int));
  normalize_map=(Quantum *) AllocateMemory((MaxRGB+1)*sizeof(Quantum));
  if ((histogram == (int *) NULL) || (normalize_map == (Quantum *) NULL))
    {
      MagickWarning(ResourceLimitWarning,"Unable to normalize image",
        "Memory allocation failed");
      return;
    }
  /*
    Form histogram.
  */
  for (i=0; i <= MaxRGB; i++)
    histogram[i]=0;
  for (y=0; y < (int) image->rows; y++)
  {
    p=GetPixelCache(image,0,y,image->columns,1);
    if (p == (PixelPacket *) NULL)
      break;
    for (x=0; x < (int) image->columns; x++)
    {
      gray_value=Intensity(*p);
      histogram[gray_value]++;
      p++;
    }
  }
  /*
    Find the histogram boundaries by locating the 1 percent levels.
  */
  threshold_intensity=(image->columns*image->rows)/100;
  intensity=0;
  for (low=0; low < MaxRGB; low++)
  {
    intensity+=histogram[low];
    if (intensity > threshold_intensity)
      break;
  }
  intensity=0;
  for (high=MaxRGB; high != 0; high--)
  {
    intensity+=histogram[high];
    if (intensity > threshold_intensity)
      break;
  }
  if (low == high)
    {
      /*
        Unreasonable contrast;  use zero threshold to determine boundaries.
      */
      threshold_intensity=0;
      intensity=0;
      for (low=0; low < MaxRGB; low++)
      {
        intensity+=histogram[low];
        if (intensity > threshold_intensity)
          break;
      }
      intensity=0;
      for (high=MaxRGB; high != 0; high--)
      {
        intensity+=histogram[high];
        if (intensity > threshold_intensity)
          break;
      }
      if (low == high)
        return;  /* zero span bound */
    }
  /*
    Stretch the histogram to create the normalized image mapping.
  */
  for (i=0; i <= MaxRGB; i++)
    if (i < (int) low)
      normalize_map[i]=0;
    else
      if (i > (int) high)
        normalize_map[i]=MaxRGB;
      else
        normalize_map[i]=(MaxRGB-1)*(i-low)/(high-low);
  /*
    Normalize the image.
  */
  switch (image->class)
  {
    case DirectClass:
    default:
    {
      /*
        Normalize DirectClass image.
      */
      for (y=0; y < (int) image->rows; y++)
      {
        q=GetPixelCache(image,0,y,image->columns,1);
        if (q == (PixelPacket *) NULL)
          break;
        for (x=0; x < (int) image->columns; x++)
        {
          q->red=normalize_map[q->red];
          q->green=normalize_map[q->green];
          q->blue=normalize_map[q->blue];
          q++;
        }
        if (!SyncPixelCache(image))
          break;
        if (QuantumTick(y,image->rows))
          ProgressMonitor(NormalizeImageText,y,image->rows);
      }
      break;
    }
    case PseudoClass:
    {
      /*
        Normalize PseudoClass image.
      */
      for (i=0; i < (int) image->colors; i++)
      {
        image->colormap[i].red=normalize_map[image->colormap[i].red];
        image->colormap[i].green=normalize_map[image->colormap[i].green];
        image->colormap[i].blue=normalize_map[image->colormap[i].blue];
      }
      SyncImage(image);
      break;
    }
  }
  FreeMemory(normalize_map);
  FreeMemory(histogram);
}
Пример #4
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%     C o n t r a s t I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method ContrastImage enhances the intensity differences between the
%  lighter and darker elements of the image.
%
%  The format of the ContrastImage method is:
%
%      void ContrastImage(Image *image,const unsigned int sharpen)
%
%  A description of each parameter follows:
%
%    o image: The address of a structure of type Image;  returned from
%      ReadImage.
%
%    o sharpen: If True, the intensity is increased otherwise it is
%      decreased.
%
%
*/
Export void ContrastImage(Image *image,const unsigned int sharpen)
{
#define DullContrastImageText  "  Dulling image contrast...  "
#define SharpenContrastImageText  "  Sharpening image contrast...  "

  int
    sign,
    y;

  register int
    i,
    x;

  register PixelPacket
    *q;

  assert(image != (Image *) NULL);
  sign=sharpen ? 1 : -1;
  switch (image->class)
  {
    case DirectClass:
    default:
    {
      /*
        Contrast enhance DirectClass image.
      */
      for (y=0; y < (int) image->rows; y++)
      {
        q=GetPixelCache(image,0,y,image->columns,1);
        if (q == (PixelPacket *) NULL)
          break;
        for (x=0; x < (int) image->columns; x++)
        {
          Contrast(sign,&q->red,&q->green,&q->blue);
          q++;
        }
        if (!SyncPixelCache(image))
          break;
        if (QuantumTick(y,image->rows))
          {
            if (sharpen)
              ProgressMonitor(SharpenContrastImageText,y,image->rows);
            else
              ProgressMonitor(DullContrastImageText,y,image->rows);
          }
      }
      break;
    }
    case PseudoClass:
    {
      Quantum
        blue,
        green,
        red;

      /*
        Contrast enhance PseudoClass image.
      */
      for (i=0; i < (int) image->colors; i++)
      {
        red=image->colormap[i].red;
        green=image->colormap[i].green;
        blue=image->colormap[i].blue;
        Contrast(sign,&red,&green,&blue);
        image->colormap[i].red=red;
        image->colormap[i].green=green;
        image->colormap[i].blue=blue;
      }
      SyncImage(image);
      break;
    }
  }
}
Пример #5
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%     M o d u l a t e I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method ModulateImage modulates the hue, saturation, and brightness of an
%  image.
%
%  The format of the ModulateImage method is:
%
%      void ModulateImage(Image *image,const char *modulate)
%
%  A description of each parameter follows:
%
%    o image: The address of a structure of type Image;  returned from
%      ReadImage.
%
%    o modulate: A character string indicating the percent change in brightness,
%      saturation, and hue in floating point notation separated by commas
%      (e.g. 10.1,0.0,3.1).
%
%
*/
Export void ModulateImage(Image *image,const char *modulate)
{
#define ModulateImageText  "  Modulating image...  "

  double
    percent_brightness,
    percent_hue,
    percent_saturation;

  int
    y;

  register int
    i,
    x;

  register PixelPacket
    *q;

  /*
    Initialize gamma table.
  */
  assert(image != (Image *) NULL);
  if (modulate == (char *) NULL)
    return;
  percent_hue=0.0;
  percent_brightness=0.0;
  percent_saturation=0.0;
  (void) sscanf(modulate,"%lf,%lf,%lf",&percent_brightness,&percent_saturation,
    &percent_hue);
  (void) sscanf(modulate,"%lf/%lf/%lf",&percent_brightness,&percent_saturation,
    &percent_hue);
  switch (image->class)
  {
    case DirectClass:
    default:
    {
      /*
        Modulate the color for a DirectClass image.
      */
      for (y=0; y < (int) image->rows; y++)
      {
        q=GetPixelCache(image,0,y,image->columns,1);
        if (q == (PixelPacket *) NULL)
          break;
        for (x=0; x < (int) image->columns; x++)
        {
          Modulate(percent_hue,percent_saturation,percent_brightness,
            &q->red,&q->green,&q->blue);
          q++;
        }
        if (!SyncPixelCache(image))
          break;
        if (QuantumTick(y,image->rows))
          ProgressMonitor(ModulateImageText,y,image->rows);
      }
      break;
    }
    case PseudoClass:
    {
      Quantum
        blue,
        green,
        red;

      /*
        Modulate the color for a PseudoClass image.
      */
      for (i=0; i < (int) image->colors; i++)
      {
        red=image->colormap[i].red;
        green=image->colormap[i].green;
        blue=image->colormap[i].blue;
        Modulate(percent_hue,percent_saturation,percent_brightness,
          &red,&green,&blue);
        image->colormap[i].red=red;
        image->colormap[i].green=green;
        image->colormap[i].blue=blue;
      }
      SyncImage(image);
      break;
    }
  }
}
Пример #6
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%     N e g a t e I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method NegateImage negates the colors in the reference image.  The
%  Grayscale option means that only grayscale values within the image are
%  negated.
%
%  The format of the NegateImage method is:
%
%      void NegateImage(Image *image,const unsigned int grayscale)
%
%  A description of each parameter follows:
%
%    o image: The address of a structure of type Image;  returned from
%      ReadImage.
%
%
*/
Export void NegateImage(Image *image,const unsigned int grayscale)
{
#define NegateImageText  "  Negating the image colors...  "

  int
    y;

  register int
    i,
    x;

  register PixelPacket
    *q;

  assert(image != (Image *) NULL);
  switch (image->class)
  {
    case DirectClass:
    default:
    {
      /*
        Negate DirectClass packets.
      */
      for (y=0; y < (int) image->rows; y++)
      {
        q=GetPixelCache(image,0,y,image->columns,1);
        if (q == (PixelPacket *) NULL)
          break;
        for (x=0; x < (int) image->columns; x++)
        {
          if (grayscale)
            if ((q->red != q->green) || (q->green != q->blue))
              {
                q++;
                continue;
              }
          q->red=(~q->red);
          q->green=(~q->green);
          q->blue=(~q->blue);
          q->opacity=(~q->opacity);
          q++;
        }
        if (!SyncPixelCache(image))
          break;
        if (QuantumTick(y,image->rows))
          ProgressMonitor(NegateImageText,y,image->rows);
      }
      break;
    }
    case PseudoClass:
    {
      /*
        Negate PseudoClass packets.
      */
      for (i=0; i < (int) image->colors; i++)
      {
        if (grayscale)
          if ((image->colormap[i].red != image->colormap[i].green) ||
              (image->colormap[i].green != image->colormap[i].blue))
            continue;
        image->colormap[i].red=(Quantum) (~image->colormap[i].red);
        image->colormap[i].green=(Quantum) (~image->colormap[i].green);
        image->colormap[i].blue=(Quantum) (~image->colormap[i].blue);
      }
      SyncImage(image);
      break;
    }
  }
}
Пример #7
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%     G a m m a I m a g e                                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method GammaImage converts the reference image to gamma corrected colors.
%
%  The format of the GammaImage method is:
%
%      void GammaImage(Image *image,const char *gamma)
%
%  A description of each parameter follows:
%
%    o image: The address of a structure of type Image;  returned from
%      ReadImage.
%
%    o gamma: A character string indicating the level of gamma correction.
%
%
*/
Export void GammaImage(Image *image,const char *gamma)
{
#define GammaImageText  "  Gamma correcting the image...  "

  double
    blue_gamma,
    green_gamma,
    opacity_gamma,
    red_gamma;

  int
    count,
    y;

  register int
    i,
    x;

  register PixelPacket
    *q;

  PixelPacket
    *gamma_map;

  assert(image != (Image *) NULL);
  if (gamma == (char *) NULL)
    return;
  red_gamma=1.0;
  green_gamma=1.0;
  blue_gamma=1.0;
  opacity_gamma=1.0;
  count=sscanf(gamma,"%lf,%lf,%lf,%lf",&red_gamma,&green_gamma,&blue_gamma,
    &opacity_gamma);
  count=sscanf(gamma,"%lf/%lf/%lf/%lf",&red_gamma,&green_gamma,&blue_gamma,
    &opacity_gamma);
  if (count == 1)
    {
      if (red_gamma == 1.0)
        return;
      green_gamma=red_gamma;
      blue_gamma=red_gamma;
    }
  /*
    Allocate and initialize gamma maps.
  */
  gamma_map=(PixelPacket *) AllocateMemory((MaxRGB+1)*sizeof(PixelPacket));
  if (gamma_map == (PixelPacket *) NULL)
    {
      MagickWarning(ResourceLimitWarning,"Unable to gamma correct image",
        "Memory allocation failed");
      return;
    }
  for (i=0; i <= MaxRGB; i++)
  {
    gamma_map[i].red=0;
    gamma_map[i].green=0;
    gamma_map[i].blue=0;
    gamma_map[i].opacity=0;
  }
  /*
    Initialize gamma table.
  */
  for (i=0; i <= MaxRGB; i++)
  {
    if (red_gamma != 0.0)
      gamma_map[i].red=(Quantum)
        ((pow((double) i/MaxRGB,1.0/red_gamma)*MaxRGB)+0.5);
    if (green_gamma != 0.0)
      gamma_map[i].green=(Quantum)
        ((pow((double) i/MaxRGB,1.0/green_gamma)*MaxRGB)+0.5);
    if (blue_gamma != 0.0)
      gamma_map[i].blue=(Quantum)
        ((pow((double) i/MaxRGB,1.0/blue_gamma)*MaxRGB)+0.5);
    if (opacity_gamma != 0.0)
      gamma_map[i].opacity=(Quantum)
        ((pow((double) i/MaxRGB,1.0/opacity_gamma)*MaxRGB)+0.5);
  }
  switch (image->class)
  {
    case DirectClass:
    default:
    {
      /*
        Gamma-correct DirectClass image.
      */
      for (y=0; y < (int) image->rows; y++)
      {
        q=GetPixelCache(image,0,y,image->columns,1);
        if (q == (PixelPacket *) NULL)
          break;
        for (x=0; x < (int) image->columns; x++)
        {
          q->red=gamma_map[q->red].red;
          q->green=gamma_map[q->green].green;
          q->blue=gamma_map[q->blue].blue;
          q->opacity=gamma_map[q->opacity].opacity;
          q++;
        }
        if (!SyncPixelCache(image))
          break;
        if (QuantumTick(y,image->rows))
          ProgressMonitor(GammaImageText,y,image->rows);
      }
      break;
    }
    case PseudoClass:
    {
      /*
        Gamma-correct PseudoClass image.
      */
      for (i=0; i < (int) image->colors; i++)
      {
        image->colormap[i].red=gamma_map[image->colormap[i].red].red;
        image->colormap[i].green=gamma_map[image->colormap[i].green].green;
        image->colormap[i].blue=gamma_map[image->colormap[i].blue].blue;
      }
      SyncImage(image);
      break;
    }
  }
  if (image->gamma != 0.0)
    image->gamma*=(red_gamma+green_gamma+blue_gamma)/3.0;
  FreeMemory(gamma_map);
}
Пример #8
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%     E q u a l i z e I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method EqualizeImage performs histogram equalization on the reference
%  image.
%
%  The format of the EqualizeImage method is:
%
%      void EqualizeImage(Image *image)
%
%  A description of each parameter follows:
%
%    o image: The address of a structure of type Image;  returned from
%      ReadImage.
%
%
*/
Export void EqualizeImage(Image *image)
{
#define EqualizeImageText  "  Equalizing image...  "

  int
    j,
    y;

  Quantum
    *equalize_map;

  register int
    i,
    x;

  register PixelPacket
    *p,
    *q;

  unsigned int
    high,
    *histogram,
    low,
    *map;

  /*
    Allocate and initialize histogram arrays.
  */
  assert(image != (Image *) NULL);
  histogram=(unsigned int *) AllocateMemory((MaxRGB+1)*sizeof(unsigned int));
  map=(unsigned int *) AllocateMemory((MaxRGB+1)*sizeof(unsigned int));
  equalize_map=(Quantum *) AllocateMemory((MaxRGB+1)*sizeof(Quantum));
  if ((histogram == (unsigned int *) NULL) || (map == (unsigned int *) NULL) ||
      (equalize_map == (Quantum *) NULL))
    {
      MagickWarning(ResourceLimitWarning,"Unable to equalize image",
        "Memory allocation failed");
      return;
    }
  /*
    Form histogram.
  */
  for (i=0; i <= MaxRGB; i++)
    histogram[i]=0;
  for (y=0; y < (int) image->rows; y++)
  {
    p=GetPixelCache(image,0,y,image->columns,1);
    if (p == (PixelPacket *) NULL)
      break;
    for (x=0; x < (int) image->columns; x++)
    {
      histogram[Intensity(*p)]++;
      p++;
    }
  }
  /*
    Integrate the histogram to get the equalization map.
  */
  j=0;
  for (i=0; i <= MaxRGB; i++)
  {
    j+=histogram[i];
    map[i]=j;
  }
  FreeMemory(histogram);
  if (map[MaxRGB] == 0)
    {
      FreeMemory(equalize_map);
      FreeMemory(map);
      return;
    }
  /*
    Equalize.
  */
  low=map[0];
  high=map[MaxRGB];
  for (i=0; i <= MaxRGB; i++)
    equalize_map[i]=(Quantum)
      ((((double) (map[i]-low))*MaxRGB)/Max(high-low,1));
  FreeMemory(map);
  /*
    Stretch the histogram.
  */
  switch (image->class)
  {
    case DirectClass:
    default:
    {
      /*
        Equalize DirectClass packets.
      */
      for (y=0; y < (int) image->rows; y++)
      {
        q=GetPixelCache(image,0,y,image->columns,1);
        if (q == (PixelPacket *) NULL)
          break;
        for (x=0; x < (int) image->columns; x++)
        {
          q->red=equalize_map[q->red];
          q->green=equalize_map[q->green];
          q->blue=equalize_map[q->blue];
          q++;
        }
        if (!SyncPixelCache(image))
          break;
        if (QuantumTick(y,image->rows))
          ProgressMonitor(EqualizeImageText,y,image->rows);
      }
      break;
    }
    case PseudoClass:
    {
      /*
        Equalize PseudoClass packets.
      */
      for (i=0; i < (int) image->colors; i++)
      {
        image->colormap[i].red=equalize_map[image->colormap[i].red];
        image->colormap[i].green=equalize_map[image->colormap[i].green];
        image->colormap[i].blue=equalize_map[image->colormap[i].blue];
      }
      SyncImage(image);
      break;
    }
  }
  FreeMemory(equalize_map);
}
Пример #9
0
Export Image *MontageImages(const Image *images,const MontageInfo *montage_info)
{
#define MontageImageText  "  Creating visual image directory...  "
#define TileImageText  "  Creating image tiles...  "

  AnnotateInfo
    *annotate_info;

  char
    geometry[MaxTextExtent];

  FrameInfo
    frame_info;

  Image
    *image,
    **image_list,
    **master_list,
    *montage_image,
    *texture,
    *tiled_image;

  ImageInfo
    *local_info;

  int
    x,
    x_offset,
    y,
    y_offset;

  MonitorHandler
    handler;

  register int
    i;

  register PixelPacket
    *q;

  RectangleInfo
    bounding_box,
    tile_info;

  unsigned int
    border_width,
    bevel_width,
    concatenate,
    count,
    font_height,
    height,
    images_per_page,
    max_height,
    number_images,
    number_lines,
    tile,
    tiles,
    tiles_per_column,
    tiles_per_row,
    tiles_per_page,
    title_offset,
    total_tiles,
    width;

  assert(images != (Image *) NULL);
  assert(montage_info != (MontageInfo *) NULL);
  /*
    Convert image list to an image group.
  */
  image_list=ListToGroupImage(images,&number_images);
  if (image_list == (Image **) NULL)
    {
      MagickWarning(ResourceLimitWarning,"Unable to montage image_list",
        "Memory allocation failed");
      return((Image *) NULL);
    }
  master_list=image_list;
  /*
    Create image tiles.
  */
  for (tile=0; tile < number_images; tile++)
  {
    handler=SetMonitorHandler((MonitorHandler) NULL);
    width=image_list[tile]->columns;
    height=image_list[tile]->rows;
    x=0;
    y=0;
    (void) ParseImageGeometry(montage_info->geometry,&x,&y,&width,&height);
    image_list[tile]->orphan=True;
    tiled_image=ZoomImage(image_list[tile],width,height);
    if (tiled_image == (Image *) NULL)
      {
        for (i=0; i < (int) tile; i++)
          DestroyImage(image_list[i]);
        (void) SetMonitorHandler(handler);
        return((Image *) NULL);
      }
    image_list[tile]=tiled_image;
    (void) SetMonitorHandler(handler);
    ProgressMonitor(TileImageText,tile,number_images);
  }
  /*
    Sort image_list by increasing tile number.
  */
  for (tile=0; tile < number_images; tile++)
    if (image_list[tile]->scene == 0)
      break;
  if (tile == number_images)
    qsort((void *) image_list,number_images,sizeof(Image *),
      (int (*)(const void *, const void *)) SceneCompare);
  /*
    Determine tiles per row and column.
  */
  tiles_per_row=1;
  tiles_per_column=1;
  while ((tiles_per_row*tiles_per_column) < number_images)
  {
    tiles_per_row++;
    tiles_per_column++;
  }
  if (montage_info->tile != (char *) NULL)
    {
      tiles_per_column=number_images;
      x=0;
      y=0;
      (void) ParseGeometry(montage_info->tile,&x,&y,&tiles_per_row,
        &tiles_per_column);
    }
  /*
    Determine tile sizes.
  */
  border_width=montage_info->border_width;
  bevel_width=0;
  if (montage_info->frame != (char *) NULL)
    {
      int
        flags;

      frame_info.width=0;
      frame_info.height=0;
      frame_info.outer_bevel=0;
      frame_info.inner_bevel=0;
      flags=ParseGeometry(montage_info->frame,&frame_info.outer_bevel,
        &frame_info.inner_bevel,&frame_info.width,&frame_info.height);
      if ((flags & HeightValue) == 0)
        frame_info.height=frame_info.width;
      if ((flags & XValue) == 0)
        frame_info.outer_bevel=(frame_info.width >> 2)+1;
      if ((flags & YValue) == 0)
        frame_info.inner_bevel=frame_info.outer_bevel;
      frame_info.x=frame_info.width;
      frame_info.y=frame_info.height;
      bevel_width=Max(frame_info.inner_bevel,frame_info.outer_bevel);
      border_width=Max(frame_info.width,frame_info.height);
    }
Пример #10
0
Файл: sct.c Проект: vgck/opendr2
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d S C T I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method ReadSCTImage reads a Scitex image file and returns it.  It allocates
%  the memory necessary for the new Image structure and returns a pointer to
%  the new image.
%
%  The format of the ReadSCTImage method is:
%
%      Image *ReadSCTImage(const ImageInfo *image_info)
%
%  A description of each parameter follows:
%
%    o image:  Method ReadSCTImage returns a pointer to the image after
%      reading.  A null image is returned if there is a memory shortage or
%      if the image cannot be read.
%
%    o image_info: Specifies a pointer to an ImageInfo structure.
%
%
*/
Export Image *ReadSCTImage(const ImageInfo *image_info)
{
  char
    buffer[768],
    magick[2];

  Image
    *image;

  int
    y;

  register int
    x;

  register PixelPacket
    *q;

  unsigned int
    status;

  /*
    Allocate image structure.
  */
  image=AllocateImage(image_info);
  if (image == (Image *) NULL)
    return((Image *) NULL);
  /*
    Open image file.
  */
  status=OpenBlob(image_info,image,ReadBinaryType);
  if (status == False)
    ReaderExit(FileOpenWarning,"Unable to open file",image);
  /*
    Read control block.
  */
  (void) ReadBlob(image,80,(char *) buffer);
  (void) ReadBlob(image,2,(char *) magick);
  if ((strncmp((char *) magick,"CT",2) != 0) &&
      (strncmp((char *) magick,"LW",2) != 0) &&
      (strncmp((char *) magick,"BM",2) != 0) &&
      (strncmp((char *) magick,"PG",2) != 0) &&
      (strncmp((char *) magick,"TX",2) != 0))
    ReaderExit(CorruptImageWarning,"Not a SCT image file",image);
  if ((strncmp((char *) magick,"LW",2) == 0) ||
      (strncmp((char *) magick,"BM",2) == 0) ||
      (strncmp((char *) magick,"PG",2) == 0) ||
      (strncmp((char *) magick,"TX",2) == 0))
    ReaderExit(CorruptImageWarning,"only Continuous Tone Picture supported",
      image);
  (void) ReadBlob(image,174,(char *) buffer);
  (void) ReadBlob(image,768,(char *) buffer);
  /*
    Read paramter block.
  */
  (void) ReadBlob(image,32,(char *) buffer);
  (void) ReadBlob(image,14,(char *) buffer);
  image->rows=atoi(buffer);
  (void) ReadBlob(image,14,(char *) buffer);
  image->columns=atoi(buffer);
  (void) ReadBlob(image,196,(char *) buffer);
  (void) ReadBlob(image,768,(char *) buffer);
  if (image_info->ping)
    {
      CloseBlob(image);
      return(image);
    }
  /*
    Convert SCT raster image to pixel packets.
  */
  image->colorspace=CMYKColorspace;
  for (y=0; y < (int) image->rows; y++)
  {
    q=SetPixelCache(image,0,y,image->columns,1);
    if (q == (PixelPacket *) NULL)
      break;
    for (x=0; x < (int) image->columns; x++)
    {
      q->red=MaxRGB-UpScale(ReadByte(image));
      q++;
    }
    if ((image->columns % 2) != 0)
      (void) ReadByte(image);  /* pad */
    q=GetPixelCache(image,0,y,image->columns,1);
    if (q == (PixelPacket *) NULL)
      break;
    for (x=0; x < (int) image->columns; x++)
    {
      q->green=MaxRGB-UpScale(ReadByte(image));
      q++;
    }
    if ((image->columns % 2) != 0)
      (void) ReadByte(image);  /* pad */
    q=GetPixelCache(image,0,y,image->columns,1);
    if (q == (PixelPacket *) NULL)
      break;
    for (x=0; x < (int) image->columns; x++)
    {
      q->blue=MaxRGB-UpScale(ReadByte(image));
      q++;
    }
    if ((image->columns % 2) != 0)
      (void) ReadByte(image);  /* pad */
    q=GetPixelCache(image,0,y,image->columns,1);
    if (q == (PixelPacket *) NULL)
      break;
    for (x=0; x < (int) image->columns; x++)
    {
      q->opacity=MaxRGB-UpScale(ReadByte(image));
      q++;
    }
    if (!SyncPixelCache(image))
      break;
    if ((image->columns % 2) != 0)
      (void) ReadByte(image);  /* pad */
    if (QuantumTick(y,image->rows))
      ProgressMonitor(LoadImageText,y,image->rows);
  }
  return(image);
}
Пример #11
0
/* The code of GIFEncodeImage is based on an early version of ImageMagick. */
static unsigned int GIFEncodeImage(GenBuffer::Writable& out, char const*ppbeg, register char const*ppend, const unsigned int data_size)
{
#define MaxCode(number_bits)  ((1 << (number_bits))-1)
#define MaxHashTable  5003
#define MaxGIFBits  12
#if defined(HasLZW)
#define MaxGIFTable  (1 << MaxGIFBits)
#else
#define MaxGIFTable  max_code
#endif
#define GIFOutputCode(code) \
{ \
  /*  \
    Emit a code. \
  */ \
  if (bits > 0) \
    datum|=((long) code << bits); \
  else \
    datum=(long) code; \
  bits+=number_bits; \
  while (bits >= 8) \
  { \
    /*  \
      Add a character to current packet. \
    */ \
    packet[byte_count++]=(unsigned char) (datum & 0xff); \
    if (byte_count >= 254) \
      { \
        packet[-1]=byte_count; \
        out.vi_write((char*)packet-1, byte_count+1); \
        byte_count=0; \
      } \
    datum>>=8; \
    bits-=8; \
  } \
  if (free_code > max_code)  \
    { \
      number_bits++; \
      if (number_bits == MaxGIFBits) \
        max_code=MaxGIFTable; \
      else \
        max_code=MaxCode(number_bits); \
    } \
}

  int
    bits,
    byte_count,
    i,
    next_pixel,
    number_bits;

  long
    datum;

  register int
    displacement,
    k;
    
  register char const*pp;

  short
    clear_code,
    end_of_information_code,
    free_code,
    *hash_code,
    *hash_prefix,
    index,
    max_code,
    waiting_code;

  unsigned char
    *packet,
    *hash_suffix;

  /*
    Allocate encoder tables.
  */
  AALLOC(packet,257,unsigned char);
  AALLOC(hash_code,MaxHashTable,short);
  AALLOC(hash_prefix,MaxHashTable,short);
  AALLOC(hash_suffix,MaxHashTable,unsigned char);
  if ((packet == (unsigned char *) NULL) || (hash_code == (short *) NULL) ||
      (hash_prefix == (short *) NULL) ||
      (hash_suffix == (unsigned char *) NULL))
    return(False);
  packet++;
  /* Now: packet-1 == place for byte_count */
  /*
    Initialize GIF encoder.
  */
  number_bits=data_size;
  max_code=MaxCode(number_bits);
  clear_code=((short) 1 << (data_size-1));
  end_of_information_code=clear_code+1;
  free_code=clear_code+2;
  byte_count=0;
  datum=0;
  bits=0;
  for (i=0; i < MaxHashTable; i++)
    hash_code[i]=0;
  GIFOutputCode(clear_code);
  /*
    Encode pixels.
  */
  /**** pts ****/
  pp=ppbeg;
  waiting_code=*(unsigned char const*)pp++; /* unsigned char BUGFIX at Sun Dec  8 13:17:00 CET 2002 */

  while (pp!=ppend) {
      /*
        Probe hash table.
      */
      index=*(unsigned char const*)pp++;
      k=(int) ((int) index << (MaxGIFBits-8))+waiting_code;
      if (k >= MaxHashTable)
        k-=MaxHashTable;
#if defined(HasLZW)
      if (hash_code[k] > 0)
        {
          if ((hash_prefix[k] == waiting_code) && (hash_suffix[k] == index))
            {
              waiting_code=hash_code[k];
              continue;
            }
          if (k == 0)
            displacement=1;
          else
            displacement=MaxHashTable-k;
          next_pixel=False;
          for ( ; ; )
          {
            k-=displacement;
            if (k < 0)
              k+=MaxHashTable;
            if (hash_code[k] == 0)
              break;
            if ((hash_prefix[k] == waiting_code) && (hash_suffix[k] == index))
              {
                waiting_code=hash_code[k];
                next_pixel=True;
                break;
              }
          }
          if (next_pixel != False) /* pacify VC6.0 */
            continue;
        }
#endif
      GIFOutputCode(waiting_code);
      // printf("wc=%u\n", waiting_code);
      if (free_code < MaxGIFTable)
        {
          hash_code[k]=free_code++;
          hash_prefix[k]=waiting_code;
          hash_suffix[k]=index;
        }
      else
        {
          /*
            Fill the hash table with empty entries.
          */
          for (k=0; k < MaxHashTable; k++)
            hash_code[k]=0;
          /*
            Reset compressor and issue a clear code.
          */
          free_code=clear_code+2;
          GIFOutputCode(clear_code);
          number_bits=data_size;
          max_code=MaxCode(number_bits);
        }
      waiting_code=index;
#if 0 /**** pts ****/
      if (QuantumTick(i,image) && (image->previous == (Image2 *) NULL))
        ProgressMonitor(SaveImageText,i,image->packets);
#endif
  }
  /*
    Flush out the buffered code.
  */
  GIFOutputCode(waiting_code);
  GIFOutputCode(end_of_information_code);
  if (bits > 0)
    {
      /*
        Add a character to current packet.
      */
      packet[byte_count++]=(unsigned char) (datum & 0xff);
      if (byte_count >= 254)
        {
          packet[-1]=byte_count;
          out.vi_write((char*)packet-1, byte_count+1);
          byte_count=0;
        }
    }
  /*
    Flush accumulated data.
  */
  if (byte_count > 0)
    {
      packet[-1]=byte_count;
      out.vi_write((char*)packet-1, byte_count+1);
    }
  /*
    Free encoder memory.
  */
  AFREE(hash_suffix);
  AFREE(hash_prefix);
  AFREE(hash_code);
  AFREE(packet-1);
  return pp==ppend;
}