ftp.nice.ch/pub/next/unix/graphics/ImageMagick.3.8.6.s.tar.gz#/ImageMagick/combine.c

This is combine.c in view mode; [Download] [Up]

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%                CCCC   OOO   M   M  BBBB   IIIII  N   N  EEEEE               %
%               C      O   O  MM MM  B   B    I    NN  N  E                   %
%               C      O   O  M M M  BBBB     I    N N N  EEE                 %
%               C      O   O  M   M  B   B    I    N  NN  E                   %
%                CCCC   OOO   M   N  BBBB   IIIII  N   N  EEEEE               %
%                                                                             %
%                                                                             %
%                        Digitally combine two images.                        %
%                                                                             %
%                                                                             %
%                                                                             %
%                              Software Design                                %
%                                John Cristy                                  %
%                               January 1993                                  %
%                                                                             %
%                                                                             %
%  Copyright 1997 E. I. Dupont de Nemours and Company                         %
%                                                                             %
%  Permission to use, copy, modify, distribute, and sell this software and    %
%  its documentation for any purpose is hereby granted without fee,           %
%  provided that the above Copyright notice appear in all copies and that     %
%  both that Copyright notice and this permission notice appear in            %
%  supporting documentation, and that the name of E. I. Dupont de Nemours     %
%  and Company not be used in advertising or publicity pertaining to          %
%  distribution of the software without specific, written prior               %
%  permission.  E. I. Dupont de Nemours and Company makes no representations  %
%  about the suitability of this software for any purpose.  It is provided    %
%  "as is" without express or implied warranty.                               %
%                                                                             %
%  E. I. Dupont de Nemours and Company disclaims all warranties with regard   %
%  to this software, including all implied warranties of merchantability      %
%  and fitness, in no event shall E. I. Dupont de Nemours and Company be      %
%  liable for any special, indirect or consequential damages or any           %
%  damages whatsoever resulting from loss of use, data or profits, whether    %
%  in an action of contract, negligence or other tortious action, arising     %
%  out of or in connection with the use or performance of this software.      %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  The combine program syntax is:
%
%  Usage: combine [options ...] image composite [mask] combined
%
%  Where options include:
%    -blend value        blend the two images a given percent
%    -colors value       preferred number of colors in the image
%    -compose operator   composite operator
%    -colorspace type    GRAY, OHTA, RGB, XYZ, YCbCr, YIQ, YPbPr, or YUV
%    -comment string     annotate image with comment
%    -compress type      RunlengthEncoded or Zip
%    -density geometry   vertical and horizontal density of the image
%    -displace geometry  shift image pixels as defined by a displacement map
%    -display server     obtain image or font from this X server
%    -dispose method     GIF disposal method
%    -dither             apply Floyd/Steinberg error diffusion to image
%    -font name          X11 font for displaying text
%    -geometry geometry  perferred size or location of the image
%    -gravity direction  which direction to gravitate towards
%    -interlace type     None, Line, Plane, or Partition
%    -label name         assign a label to an image
%    -matte              store matte channel if the image has one
%    -monochrome         transform image to black and white
%    -negate              apply color inversion to image
%    -page geometry      size and location of the Postscript page
%    -quality value      JPEG quality setting
%    -scene value        image scene number
%    -size geometry      width and height of image
%    -stereo             combine two images to form red-green stereo image
%    -tile               repeat composite operation across image
%    -treedepth value    depth of the color classification tree
%    -verbose            print detailed information about the image
%
%  Change '-' to '+' in any option above to reverse its effect.  For
%  example,  specify +matte to store the image without its matte channel.
%
%
*/

/*
  Include declarations.
*/
#include "magick.h"
#include "version.h"

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   U s a g e                                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Procedure Usage displays the program usage;
%
%  The format of the Usage routine is:
%
%      Usage(client_name)
%
%    o client_name: a character string representing the name of the client
%      program.
%
%
*/
static void Usage(const char *client_name)
{
  char
    **p;

  static char
    *options[]=
    {
      "-blend value        blend the two images a given percent",
      "-colors value       preferred number of colors in the image",
      "-colorspace type    GRAY, OHTA, RGB, XYZ, YCbCr, YIQ, YPbPr, or YUV",
      "-comment string     annotate image with comment",
      "-compose operator   composite operator",
      "-compress type      RunlengthEncoded or Zip",
      "-density geometry   vertical and horizontal density of the image",
      "-displace geometry  shift image pixels as defined by a displacement map",
      "-display server     obtain image or font from this X server",
      "-dispose method     GIF disposal method",
      "-dither             apply Floyd/Steinberg error diffusion to image",
      "-font name          X11 font for displaying text",
      "-geometry geometry  perferred size or location of the image",
      "-gravity direction  which direction to gravitate towards",
      "-interlace type     None, Line, Plane, or Partition",
      "-label name         assign a label to an image",
      "-matte              store matte channel if the image has one",
      "-monochrome         transform image to black and white",
      "-negate              apply color inversion to image",
      "-page geometry      size and location of the Postscript page",
      "-quality value      JPEG quality setting",
      "-scene value        image scene number",
      "-size geometry      width and height of image",
      "-stereo             combine two images to form red-green stereo image",
      "-tile               repeat composite operation across image",
      "-treedepth value    depth of the color classification tree",
      "-verbose            print detailed information about the image",
      (char *) NULL
    };

  (void) printf("Version: %s\n\n",Version);
  (void) printf("Usage: %s [options ...] image composite [mask] combined\n",
    client_name);
  (void) printf("\nWhere options include:\n");
  for (p=options; *p != (char *) NULL; p++)
    (void) printf("  %s\n",*p);
  (void) printf(
    "\nChange '-' to '+' in any option above to reverse its effect.  For\n");
  (void) printf(
    "example,  specify +matte to store the image without an matte channel.\n");
  Exit(1);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%  M a i n                                                                    %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
*/
int main(int argc,char *argv[])
{
#define NotInitialized  (unsigned int) (~0)

  char
    *client_name,
    *displacement_geometry,
    *filename,
    *geometry,
    *option,
    *write_filename;

  CompositeOperator
    compose;

  double
    blend;

  Image
    *combined_image,
    *composite_image,
    *image,
    *mask_image;

  ImageInfo
    image_info;

  int
    gravity,
    x,
    y;

  register int
    i;

  unsigned int
    colorspace,
    stereo,
    tile;

  /*
    Initialize program variables.
  */
  ReadCommandlLine(argc,&argv);
  client_name=ClientName(*argv);
  if (argc < 4)
    Usage(client_name);
  /*
    Read image and convert to MIFF format.
  */
  blend=0.0;
  colorspace=RGBColorspace;
  compose=ReplaceCompositeOp;
  composite_image=(Image *) NULL;
  displacement_geometry=(char *) NULL;
  geometry=(char *) NULL;
  gravity=NorthWestGravity;
  GetImageInfo(&image_info);
  image=(Image *) NULL;
  mask_image=(Image *) NULL;
  stereo=False;
  tile=False;
  write_filename=argv[argc-1];
  /*
    Check command syntax.
  */
  filename=(char *) NULL;
  for (i=1; i < (argc-1); i++)
  {
    option=argv[i];
    if ((Extent(option) < 2) || ((*option != '-') && (*option != '+')))
      {
        /*
          Read input images.
        */
        filename=argv[i];
        (void) strcpy(image_info.filename,filename);
        if (image == (Image *) NULL)
          {
            image=ReadImage(&image_info);
            if (image == (Image *) NULL)
              Exit(1);
            continue;
          }
        if (mask_image != (Image *) NULL)
          Error("input images already specified",filename);
        if (composite_image == (Image *) NULL)
          {
            composite_image=ReadImage(&image_info);
            if (composite_image == (Image *) NULL)
              Exit(1);
            continue;
          }
        mask_image=ReadImage(&image_info);
        if (mask_image == (Image *) NULL)
          Exit(1);
      }
    else
      switch(*(option+1))
      {
        case 'b':
        {
          if (strncmp("blend",option+1,3) == 0)
            {
              blend=0.0;
              if (*option == '-')
                {
                  i++;
                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
                    Error("Missing value on -blend",(char *) NULL);
                  blend=atof(argv[i]);
                  compose=BlendCompositeOp;
                }
              break;
            }
          Error("Unrecognized option",option);
          break;
        }
        case 'c':
        {
          if (strncmp("colors",option+1,7) == 0)
            {
              if (*option == '-')
                {
                  i++;
                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
                    Error("Missing colors on -colors",(char *) NULL);
                }
              break;
            }
          if (strncmp("colorspace",option+1,7) == 0)
            {
              colorspace=RGBColorspace;
              if (*option == '-')
                {
                  i++;
                  if (i == argc)
                    Error("Missing type on -colorspace",(char *) NULL);
                  option=argv[i];
                  colorspace=UndefinedColorspace;
                  if (Latin1Compare("gray",option) == 0)
                    colorspace=GRAYColorspace;
                  if (Latin1Compare("ohta",option) == 0)
                    colorspace=OHTAColorspace;
                  if (Latin1Compare("rgb",option) == 0)
                    colorspace=RGBColorspace;
                  if (Latin1Compare("transparent",option) == 0)
                    colorspace=TransparentColorspace;
                  if (Latin1Compare("xyz",option) == 0)
                    colorspace=XYZColorspace;
                  if (Latin1Compare("ycbcr",option) == 0)
                    colorspace=YCbCrColorspace;
                  if (Latin1Compare("yiq",option) == 0)
                    colorspace=YIQColorspace;
                  if (Latin1Compare("ypbpr",option) == 0)
                    colorspace=YPbPrColorspace;
                  if (Latin1Compare("yuv",option) == 0)
                    colorspace=YUVColorspace;
                  if (colorspace == UndefinedColorspace)
                    Error("Invalid colorspace type on -colorspace",option);
                }
              break;
            }
          if (strncmp("comment",option+1,4) == 0)
            {
              if (*option == '-')
                {
                  i++;
                  if (i == argc)
                    Error("Missing comment on -comment",(char *) NULL);
                }
              break;
            }
          if (strncmp("compose",option+1,5) == 0)
            {
              compose=ReplaceCompositeOp;
              if (*option == '-')
                {
                  i++;
                  if (i == argc)
                    Error("Missing type on -compose",(char *) NULL);
                  option=argv[i];
                  compose=UndefinedCompositeOp;
                  if (Latin1Compare("over",option) == 0)
                    compose=OverCompositeOp;
                  if (Latin1Compare("in",option) == 0)
                    compose=InCompositeOp;
                  if (Latin1Compare("out",option) == 0)
                    compose=OutCompositeOp;
                  if (Latin1Compare("atop",option) == 0)
                    compose=AtopCompositeOp;
                  if (Latin1Compare("xor",option) == 0)
                    compose=XorCompositeOp;
                  if (Latin1Compare("plus",option) == 0)
                    compose=PlusCompositeOp;
                  if (Latin1Compare("minus",option) == 0)
                    compose=MinusCompositeOp;
                  if (Latin1Compare("add",option) == 0)
                    compose=AddCompositeOp;
                  if (Latin1Compare("subtract",option) == 0)
                    compose=SubtractCompositeOp;
                  if (Latin1Compare("difference",option) == 0)
                    compose=DifferenceCompositeOp;
                  if (Latin1Compare("bumpmap",option) == 0)
                    compose=BumpmapCompositeOp;
                  if (Latin1Compare("replace",option) == 0)
                    compose=ReplaceCompositeOp;
                  if (compose == UndefinedCompositeOp)
                    Error("Invalid compose type on -compose",option);
                }
              break;
            }
          if (strncmp("compress",option+1,3) == 0)
            {
              image_info.compression=NoCompression;
              if (*option == '-')
                {
                  i++;
                  if (i == argc)
                    Error("Missing type on -compress",(char *) NULL);
                  option=argv[i];
                  if (Latin1Compare("runlengthencoded",option) == 0)
                    image_info.compression=RunlengthEncodedCompression;
                  else
                    if (Latin1Compare("zip",option) == 0)
                      image_info.compression=ZipCompression;
                    else
                      Error("Invalid compression type on -compress",option);
                }
              break;
            }
          Error("Unrecognized option",option);
          break;
        }
        case 'd':
        {
          if (strncmp("density",option+1,3) == 0)
            {
              image_info.density=(char *) NULL;
              if (*option == '-')
                {
                  i++;
                  if ((i == argc) || !IsGeometry(argv[i]))
                    Error("Missing geometry on -density",(char *) NULL);
                  image_info.density=argv[i];
                }
              break;
            }
          if (strcmp("displace",option+1) == 0)
            {
              displacement_geometry=(char *) NULL;
              if (*option == '-')
                {
                  i++;
                  if ((i == argc) || !sscanf(argv[i],"%f",(float *) &x))
                    Error("Missing geometry on -displace",(char *) NULL);
                  displacement_geometry=argv[i];
                  compose=DisplaceCompositeOp;
                }
              break;
            }
          if (strcmp("display",option+1) == 0)
            {
              image_info.server_name=(char *) NULL;
              if (*option == '-')
                {
                  i++;
                  if (i == argc)
                    Error("Missing server name on -display",(char *) NULL);
                  image_info.server_name=argv[i];
                }
              break;
            }
          if (strncmp("dispose",option+1,5) == 0)
            {
              image_info.dispose=(char *) NULL;
              if (*option == '-')
                {
                  i++;
                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
                    Error("Missing method on -dispose",(char *) NULL);
                  image_info.dispose=PostscriptGeometry(argv[i]);
                }
              break;
            }
          if (strncmp("dither",option+1,3) == 0)
            {
              image_info.dither=(*option == '-');
              break;
            }
          Error("Unrecognized option",option);
          break;
        }
        case 'f':
        {
          image_info.font=(char *) NULL;
          if (*option == '-')
            {
              i++;
              if (i == argc)
                Error("Missing font name on -font",(char *) NULL);
              image_info.font=argv[i];
            }
          break;
        }
        case 'g':
        {
          if (strncmp("geometry",option+1,2) == 0)
            {
              geometry=(char *) NULL;
              if (*option == '-')
                {
                  i++;
                  if ((i == argc) || !IsGeometry(argv[i]))
                    Error("Missing geometry on -geometry",(char *) NULL);
                  geometry=argv[i];
                }
              break;
            }
          if (strncmp("gravity",option+1,2) == 0)
            {
              gravity=NorthWestGravity;
              if (*option == '-')
                {
                  i++;
                  if (i == argc)
                    Error("Missing type on -gravity",(char *) NULL);
                  option=argv[i];
                  gravity=(-1);
                  if (Latin1Compare("Forget",option) == 0)
                    gravity=ForgetGravity;
                  if (Latin1Compare("NorthWest",option) == 0)
                    gravity=NorthWestGravity;
                  if (Latin1Compare("North",option) == 0)
                    gravity=NorthGravity;
                  if (Latin1Compare("NorthEast",option) == 0)
                    gravity=NorthEastGravity;
                  if (Latin1Compare("West",option) == 0)
                    gravity=WestGravity;
                  if (Latin1Compare("Center",option) == 0)
                    gravity=CenterGravity;
                  if (Latin1Compare("East",option) == 0)
                    gravity=EastGravity;
                  if (Latin1Compare("SouthWest",option) == 0)
                    gravity=SouthWestGravity;
                  if (Latin1Compare("South",option) == 0)
                    gravity=SouthGravity;
                  if (Latin1Compare("SouthEast",option) == 0)
                    gravity=SouthEastGravity;
                  if (Latin1Compare("Static",option) == 0)
                    gravity=StaticGravity;
                  if (gravity == (-1))
                    Error("Invalid gravity type on -gravity",option);
                }
              break;
            }
          Error("Unrecognized option",option);
          break;
        }
        case 'h':
        {
          if (strncmp("help",option+1,2) == 0)
            {
              Usage(client_name);
              break;
            }
          Error("Unrecognized option",option);
          break;
        }
        case 'i':
        {
          if (strncmp("interlace",option+1,3) == 0)
            {
              image_info.interlace=NoneInterlace;
              if (*option == '-')
                {
                  i++;
                  if (i == argc)
                    Error("Missing type on -interlace",(char *) NULL);
                  option=argv[i];
                  image_info.interlace=UndefinedInterlace;
                  if (Latin1Compare("none",option) == 0)
                    image_info.interlace=NoneInterlace;
                  if (Latin1Compare("line",option) == 0)
                    image_info.interlace=LineInterlace;
                  if (Latin1Compare("plane",option) == 0)
                    image_info.interlace=PlaneInterlace;
                  if (Latin1Compare("partition",option) == 0)
                    image_info.interlace=PartitionInterlace;
                  if (image_info.interlace == UndefinedInterlace)
                    Error("Invalid interlace type on -interlace",option);
                }
              break;
            }
          Error("Unrecognized option",option);
          break;
        }
        case 'l':
        {
          if (strncmp("label",option+1,2) == 0)
            {
              if (*option == '-')
                {
                  i++;
                  if (i == argc)
                    Error("Missing label name on -label",(char *) NULL);
                }
              break;
            }
          Error("Unrecognized option",option);
          break;
        }
        case 'm':
        {
          if (strncmp("matte",option+1,5) == 0)
            break;
          if (strncmp("monochrome",option+1,2) == 0)
            break;
          Error("Unrecognized option",option);
          break;
        }
        case 'n':
        {
          if (strncmp("negate",option+1,3) == 0)
            break;
          Error("Unrecognized option",option);
          break;
        }
        case 'p':
        {
          if (strncmp("page",option+1,3) == 0)
            {
              image_info.page=(char *) NULL;
              if (*option == '-')
                {
                  i++;
                  if (i == argc)
                    Error("Missing page geometry on -page",(char *) NULL);
                  image_info.page=PostscriptGeometry(argv[i]);
                }
              break;
            }
          Error("Unrecognized option",option);
          break;
        }
        case 'q':
        {
          if (strncmp("quality",option+1,2) == 0)
            {
              image_info.quality=atoi(DefaultImageQuality);
              if (*option == '-')
                {
                  i++;
                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
                    Error("Missing quality on -quality",(char *) NULL);
                  image_info.quality=atoi(argv[i]);
                }
              break;
            }
          Error("Unrecognized option",option);
          break;
        }
        case 's':
        {
          if (strncmp("scene",option+1,2) == 0)
            {
              if (*option == '-')
                {
                  i++;
                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
                    Error("Missing scene number on -scene",(char *) NULL);
                }
              break;
            }
          if (strncmp("size",option+1,2) == 0)
            {
              image_info.size=(char *) NULL;
              if (*option == '-')
                {
                  i++;
                  if ((i == argc) || !IsGeometry(argv[i]))
                    Error("Missing geometry on -size",(char *) NULL);
                  image_info.size=argv[i];
                }
              break;
            }
          if (strncmp("stereo",option+1,2) == 0)
            {
              stereo=(*option == '-');
              break;
            }
          Error("Unrecognized option",option);
          break;
        }
        case 't':
        {
          if (strncmp("tile",option+1,2) == 0)
            {
              tile=(*option == '-');
              break;
            }
          Error("Unrecognized option",option);
          if (strncmp("treedepth",option+1,3) == 0)
            {
              if (*option == '-')
                {
                  i++;
                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
                    Error("Missing depth on -treedepth",(char *) NULL);
                }
              break;
            }
          Error("Unrecognized option",option);
          break;
        }
        case 'v':
        {
          image_info.verbose=(*option == '-');
          break;
        }
        case '?':
        {
          Usage(client_name);
          break;
        }
        default:
        {
          Error("Unrecognized option",option);
          break;
        }
      }
  }
  if ((image == (Image *) NULL) || (composite_image == (Image *) NULL))
    Usage(client_name);
  if (mask_image != (Image *) NULL)
    {
      CompositeImage(composite_image,AddMaskCompositeOp,mask_image,0,0);
      DestroyImage(mask_image);
    }
  if (compose == BlendCompositeOp)
    {
      register RunlengthPacket
        *p;

      unsigned short
        index;

      /*
        Create mattes for blending.
      */
      index=(unsigned short)
        (DownScale(MaxRGB)-(((int) DownScale(MaxRGB)*blend)/100));
      image->class=DirectClass;
      image->matte=True;
      p=image->pixels;
      for (i=0; i < image->packets; i++)
      {
        p->index=index;
        p++;
      }
      index=(unsigned short) (DownScale(MaxRGB)-index);
      composite_image->class=DirectClass;
      composite_image->matte=True;
      p=composite_image->pixels;
      for (i=0; i < composite_image->packets; i++)
      {
        p->index=index;
        p++;
      }
    }
  if (compose == DisplaceCompositeOp)
    composite_image->geometry=displacement_geometry;
  /*
    Combine image.
  */
  if (stereo)
    combined_image=StereoImage(image,composite_image);
  else
    if (tile)
      {
        /*
          Tile the composite image.
        */
        for (y=0; y < image->rows; y+=composite_image->rows)
          for (x=0; x < image->columns; x+=composite_image->columns)
            CompositeImage(image,compose,composite_image,x,y);
        combined_image=image;
      }
    else
      {
        unsigned int
          size;

        /*
          Digitally composite image.
        */
        x=0;
        y=0;
        if (geometry != (char *) NULL)
          (void) XParseGeometry(geometry,&x,&y,&size,&size);
        switch (gravity)
        {
          case NorthWestGravity:
            break;
          case NorthGravity:
          {
            x+=(image->columns-composite_image->columns) >> 1;
            break;
          }
          case NorthEastGravity:
          {
            x+=image->columns-composite_image->columns;
            break;
          }
          case WestGravity:
          {
            y+=(image->rows-composite_image->rows) >> 1;
            break;
          }
          case ForgetGravity:
          {
            char
              geometry[MaxTextExtent];

            /*
              Stretch composite to the same size as the image.
            */
            (void) sprintf(geometry,"%ux%u",image->columns,image->rows);
            TransformImage(&composite_image,(char *) NULL,geometry);
            break;
          }
          case StaticGravity:
          case CenterGravity:
          default:
          {
            x+=(image->columns-composite_image->columns) >> 1;
            y+=(image->rows-composite_image->rows) >> 1;
            break;
          }
          case EastGravity:
          {
            x+=image->columns-composite_image->columns;
            y+=(image->rows-composite_image->rows) >> 1;
            break;
          }
          case SouthWestGravity:
          {
            y+=image->rows-composite_image->rows;
            break;
          }
          case SouthGravity:
          {
            x+=(image->columns-composite_image->columns) >> 1;
            y+=image->rows-composite_image->rows;
            break;
          }
          case SouthEastGravity:
          {
            x+=image->columns-composite_image->columns;
            y+=image->rows-composite_image->rows;
            break;
          }
        }
        CompositeImage(image,compose,composite_image,x,y);
        combined_image=image;
      }
  if (combined_image == (Image *) NULL)
    Exit(1);
  /*
    Write image.
  */
  (void) strcpy(combined_image->filename,write_filename);
  /*
    Transmogrify image as defined by the image processing options.
  */
  MogrifyImage(&image_info,argc,argv,&combined_image);
  (void) WriteImage(&image_info,combined_image);
  if (image_info.verbose)
    DescribeImage(combined_image,stderr,False);
  Exit(0);
  return(False);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.