Пример #1
0
void Methods::signAlign(Mat dst)
{
	
	//find angle 
	//Image(Mat*image, int yu, int yl, int xl, int xr, Point2f temp);
	Mat temp1,temp2;
	temp1 = dst(Rect(0, 0, dst.cols / 2, dst.rows));
	temp2 = dst(Rect(dst.cols / 2, 0, dst.cols / 2, dst.rows));
	Image temp_image1(&temp1, 0, temp1.rows, 0, temp1.cols, Point2f(0, 0));
	Image temp_image2(&temp2, 0, temp2.rows, 0, temp2.cols, Point2f(0, 0));
	cout << "BEFORE\n";
	cout << temp_image1.x_left << "-Upper  down-" << temp_image1.y_lower<<"   ";
	cout << temp_image2.x_left << "-Upper  down-" << temp_image2.y_lower;
	CropImage(&temp_image1, 20);
	CropImage(&temp_image2, 20);
	cout << "\nAFTER\n";
	cout << temp_image1.x_left << "-Upper  down-" << temp_image1.y_lower << "   ";
	cout << temp_image2.x_left << "-Upper  down-" << temp_image2.y_lower << "\n\n";
	//float angle1=calculateAngle(Point2f(temp_image1.x_left, temp_image1.y_upper), Point2f(temp_image2.x_left, temp_image2.y_upper));
	float angle2 = calculateAngle(Point2f(0, temp_image1.y_lower), Point2f(1, temp_image2.y_lower));
	namedWindow("temp1", CV_WINDOW_NORMAL);
	namedWindow("temp2", CV_WINDOW_NORMAL);
	imshow("temp1", temp1);
	imshow("temp2", temp2);
	waitKey(0);
	cout << angle2<<"\n\n";
	double angle = angle2;
	rotateByAngle(dst, angle);

}
Пример #2
0
HRESULT UISeperator::Draw(DK_IMAGE drawingImg)
{
    HRESULT hr(S_OK);
    if (!m_bIsVisible)
    {
        return hr;
    }
    DK_IMAGE imgSelf;
    DK_RECT rcSelf = {m_iLeft, m_iTop, m_iLeft + m_iWidth, m_iTop + m_iHeight};
    RTN_HR_IF_FAILED(CropImage(drawingImg, rcSelf, &imgSelf));

    CTpGraphics grf(imgSelf);
    if (SD_VERT == m_direction)
    {
        grf.FillRect(m_iWidth / 2, 0,
                m_iWidth / 2 + m_thickness, m_iHeight,
                ColorManager::knBlack);
    }
    else
    {
        grf.FillRect(0, m_iHeight / 2,
                m_iWidth, m_iHeight /2 + m_thickness,
                ColorManager::knBlack);
    }
    return S_OK;
}
Пример #3
0
Mat PAN::preprocess(Mat *image, Image *output,int parameter,String database){
	output->x_left= 0;
	output->x_right = image->cols;;
	output->y_upper = 0;
	output->y_lower = image->rows;
	if (image->channels()>=2){ 
		cvtColor(*image, *output->img, CV_BGR2GRAY); 
	}
	//cropimage globally to get pan card and put it in output image
	if (parameter == 1){ 
		//assuming we have only the pancard as the image
		//going to remove emblem
		Point matchloc;
		float percentage, threshold;
		database =database+ "emblem.png";
		Mat temp = imread(database);
		if (temp.data == NULL){ cout << "hi there"; }
		templateMatch(*image, temp, matchloc, threshold, percentage);
		int width, height;
		width = temp.size().width; height = temp.size().height;
		Point boundary(matchloc.x + width, matchloc.y + height);
		if (percentage >= 85){ output->y_upper = boundary.y; }
		Mat mod(*image, Rect(Point(output->x_left, output->y_upper), Point(output->x_right, output->y_lower)));
		//imshow("test1", mod);
		//waitKey();
		return mod; }
	else if (parameter == 2){
		//initializing panimage by removing the borders
		output->img = image;
		CropImage(output,10,10,0);
		return *output->img;
	}
		
}
Пример #4
0
void MobiBookReader::DitherImage()
{
    DebugPrintf(DLC_ZHAIGH, "MobiBookReader::%s() ConvertRGB32ToGray256", __FUNCTION__);
    if (!DkFormat::DkImageHelper::ConvertRGB32ToGray256(&m_tCurPageImage))
    {
        return;
    }

    DebugPrintf(DLC_ZHAIGH, "MobiBookReader::%s() GetImageIterator", __FUNCTION__);
    IDKEImageIterator *pImageIterator = m_pPage->GetImageIterator();
    if (pImageIterator)
    {
        // 避免死循环
        for (int i = 0; i < 1000; ++i)
        {
            if (pImageIterator->MoveToNext())
            {
                DK_BOX cropBox = pImageIterator->GetCurrentImageBox();
                DK_RECT cropRect;
                cropRect.left   = (int)(cropBox.X0);
                cropRect.right  = (int)(cropBox.X1);
                cropRect.top    = (int)(cropBox.Y0);
                cropRect.bottom = (int)(cropBox.Y1);
                DK_IMAGE toDither;
                if (S_OK == CropImage(m_tCurPageImage, cropRect, &toDither))
                {
                    if (m_bIsInstant)
                    {
                        DebugPrintf(DLC_ZHAIGH, "MobiBookReader::%s() DitherGray256ToBinary", __FUNCTION__);
                        DkFormat::DkImageHelper::DitherGray256ToBinary(toDither);
                    }
                    else
                    {
                        DebugPrintf(DLC_ZHAIGH, "MobiBookReader::%s() DitherGray256ToGray16", __FUNCTION__);
                        DkFormat::DkImageHelper::DitherGray256ToGray16(toDither);
                    }
                }
            }
            else
            {
                break;
            }
        }

        m_pPage->FreeImageIterator(pImageIterator);
        pImageIterator = NULL;
    }

    if (m_bIsInstant)
    {
        DebugPrintf(DLC_ZHAIGH, "MobiBookReader::%s() ConvertGray256ToBinary", __FUNCTION__);
        DkFormat::DkImageHelper::ConvertGray256ToBinary(m_tCurPageImage);
    }
    else
    {
        DebugPrintf(DLC_ZHAIGH, "MobiBookReader::%s() ConvertGray256ToGray16", __FUNCTION__);
        DkFormat::DkImageHelper::ConvertGray256ToGray16(m_tCurPageImage);
    }
}
Пример #5
0
void QmitkImageCropper::CreateConnections()
{
  if ( m_Controls )
  {
    connect( m_Controls->btnCrop, SIGNAL(clicked()), this, SLOT(CropImage()));   // click on the crop button
    connect( m_Controls->m_NewBoxButton, SIGNAL(clicked()), this, SLOT(CreateNewBoundingObject()) );
    connect( m_Controls->m_EnableSurroundingCheckBox, SIGNAL(toggled(bool)), this, SLOT(SurroundingCheck(bool)) );
    connect( m_Controls->chkInformation, SIGNAL(toggled(bool)), this, SLOT(ChkInformationToggled(bool)) );
  }
}
Пример #6
0
Image *crop_image(Image *img, char *path, int image_width, int image_height, int width_offset, int height_offset)
{
    Image           *new_img = NULL;
    ImageInfo       *image_info;
    Image           *tmp;
    RectangleInfo   *portion;
    ExceptionInfo   exception;


    portion = malloc(sizeof(*portion));
    portion->width = image_width;
    portion->height = image_height;
    portion->x = width_offset;
    portion->y = height_offset;
    
    
    GetExceptionInfo(&exception);
    if ((image_info = CloneImageInfo((ImageInfo *)NULL)) == NULL) {
        CatchException(&exception);
        DestroyImageInfo(image_info);
        free(portion);
        return (NULL);
    }
    
    strcpy(image_info->filename, path);
    
    if ((new_img = ReadImage(image_info, &exception)) == NULL)
    {
        CatchException(&exception);
        DestroyImage(new_img);
        DestroyImageInfo(image_info);
        free(portion);
        return (NULL);
    }
    tmp = new_img;
    
    if ((new_img = CropImage(img, portion, &exception)) == NULL) {
        CatchException(&exception);
        DestroyImage(tmp);
        DestroyImageInfo(image_info);
        free(portion);
        return (NULL);
    }
    
    DestroyImage(img);
    DestroyImage(tmp);
    DestroyImageInfo(image_info);
    free(portion);
    SyncImagePixels(new_img);
    free(path);
    return (new_img);
}
Пример #7
0
static
ERL_NIF_TERM exmagick_crop (ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
  Image* cropped_image;
  RectangleInfo rect;
  exm_resource_t *resource;

  EXM_INIT;
  ErlNifResourceType *type = (ErlNifResourceType *) enif_priv_data(env);

  if (0 == enif_get_resource(env, argv[0], type, (void **) &resource))
  { EXM_FAIL(ehandler, "invalid handle"); }

  if (resource->image == NULL)
  { EXM_FAIL(ehandler, "image not loaded"); }

  /* build rectangle */
  if (0 == enif_get_long(env, argv[1], &rect.x))
  { EXM_FAIL(ehandler, "x0: bad argument"); }

  if (0 == enif_get_long(env, argv[2], &rect.y))
  { EXM_FAIL(ehandler, "y0: bad argument"); }

  if (0 == enif_get_ulong(env, argv[3], &rect.width))
  { EXM_FAIL(ehandler, "width: bad argument"); }

  if (0 == enif_get_ulong(env, argv[4], &rect.height))
  { EXM_FAIL(ehandler, "height: bad argument"); }

  /* actually crops image */
  cropped_image = CropImage(resource->image, &rect, &resource->e_info);
  if (cropped_image == NULL)
  {
    CatchException(&resource->e_info);
    EXM_FAIL(ehandler, resource->e_info.reason);
  }
  DestroyImage(resource->image);
  resource->image = cropped_image;

  return(enif_make_tuple2(env, enif_make_atom(env, "ok"), argv[0]));

ehandler:
  return(enif_make_tuple2(env, enif_make_atom(env, "error"), exmagick_make_utf8str(env, errmsg)));
}
Пример #8
0
HRESULT UIPdfTrimColumnedDlg::DrawBackGround(DK_IMAGE drawingImg) 
{
	DebugPrintf(DLC_ZHY,"enter %s:%s,%s(%d)",GetClassName(),__FUNCTION__,__FILE__,__LINE__);
	HRESULT hr(S_OK);
	DK_IMAGE imgSelf;
	DK_RECT rcSelf={m_iLeft, m_iTop, m_iWidth, m_iHeight};

	//drawing original image
	DK_IMAGE* backGroundImage = m_pBookReader->GetPageBMP();
	rcSelf.top     = m_iHeight > backGroundImage->iHeight? (m_iHeight - backGroundImage->iHeight) >> 1: m_iTop;
	rcSelf.bottom  = rcSelf.top + backGroundImage->iHeight;
	rcSelf.left    = m_iWidth > backGroundImage->iWidth? (m_iWidth - backGroundImage->iWidth) >> 1: m_iLeft;
	rcSelf.right   = rcSelf.left + backGroundImage->iWidth;
	CTpGraphics grf(drawingImg);
	grf.EraserBackGround(ColorManager::knWhite);
	RTN_HR_IF_FAILED(CropImage(drawingImg, rcSelf, &imgSelf));
	CopyImage(imgSelf, *backGroundImage);

	DebugPrintf(DLC_ZHY,"leave %s:%s,%s(%d)",GetClassName(),__FUNCTION__,__FILE__,__LINE__);
	return hr;
}
Пример #9
0
int Methods::preprocess(Mat *bin_image, vector<Image> *output,int doc) {
	Image temp_image(bin_image , 0, bin_image->rows, 0, bin_image->cols,Point2f(0,0));
	if (bin_image->channels()> 2){ cvtColor(*bin_image, *bin_image, CV_BGR2GRAY); }
	if (doc==1){
	adaptiveThreshold(*bin_image, *bin_image, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 51, 45);}
	else{
		adaptiveThreshold(*bin_image, *bin_image, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 13, 23);
	}
		int sensitivity = 4;
		CropImage(&temp_image, sensitivity);
		if (temp_image.x_right < 10 || temp_image.y_lower < 10){  return 0; }
		resize(*bin_image, *bin_image, Size(200, 100), 0, 0);
		//rotate here and then resize--1-11-2015
	//	signAlign(*bin_image);

		temp_image.y_lower = 100;
		temp_image.x_right = 200;
		temp_image.y_upper = 0;
		temp_image.x_left = 0;
		temp_image.imgCOG = calculateCOG(&temp_image);
		sampleCOG = temp_image.imgCOG;
		output->push_back(temp_image);
		return 1;
}
Пример #10
0
Image		*crop_image_from_path(char *path, RectangleInfo *portion)
{
  ImageInfo	*image_info;
  Image		*img;
  Image		*tmp;
  ExceptionInfo	exception;

  GetExceptionInfo(&exception);
  if ((image_info = CloneImageInfo((ImageInfo *)NULL)) == NULL) {
    CatchException(&exception);
    DestroyImageInfo(image_info);
    return (NULL);
  }

  strcpy(image_info->filename, path);

  if ((img = ReadImage(image_info, &exception)) == NULL)
    {
      CatchException(&exception);
      DestroyImageInfo(image_info);
      return (NULL);
    }

  tmp = img;

  if ((img = CropImage(img, portion, &exception)) == NULL) {
    CatchException(&exception);
    DestroyImage(tmp);
    DestroyImageInfo(image_info);
    return (NULL);
  }

  DestroyImage(tmp);
  DestroyImageInfo(image_info);
  return (img);
}
Пример #11
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d I m a g e                                                         %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadImage() reads an image or image sequence from a file or file handle.
%  The method returns a NULL if there is a memory shortage or if the image
%  cannot be read.  On failure, a NULL image is returned and exception
%  describes the reason for the failure.
%
%  The format of the ReadImage method is:
%
%      Image *ReadImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: Read the image defined by the file or filename members of
%      this structure.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport Image *ReadImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  char
    filename[MaxTextExtent],
    magick[MaxTextExtent],
    magick_filename[MaxTextExtent];

  const char
    *value;

  const DelegateInfo
    *delegate_info;

  const MagickInfo
    *magick_info;

  ExceptionInfo
    *sans_exception;

  GeometryInfo
    geometry_info;

  Image
    *image,
    *next;

  ImageInfo
    *read_info;

  MagickStatusType
    flags,
    thread_support;

  PolicyDomain
    domain;

  PolicyRights
    rights;

  /*
    Determine image type from filename prefix or suffix (e.g. image.jpg).
  */
  assert(image_info != (ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image_info->filename != (char *) NULL);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  read_info=CloneImageInfo(image_info);
  (void) CopyMagickString(magick_filename,read_info->filename,MaxTextExtent);
  (void) SetImageInfo(read_info,0,exception);
  (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
  (void) CopyMagickString(magick,read_info->magick,MaxTextExtent);
  domain=CoderPolicyDomain;
  rights=ReadPolicyRights;
  if (IsRightsAuthorized(domain,rights,read_info->magick) == MagickFalse)
    {
      errno=EPERM;
      (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
        "NotAuthorized","`%s'",read_info->filename);
      return((Image *) NULL);
    }
  /*
    Call appropriate image reader based on image type.
  */
  sans_exception=AcquireExceptionInfo();
  magick_info=GetMagickInfo(read_info->magick,sans_exception);
  sans_exception=DestroyExceptionInfo(sans_exception);
  if (magick_info != (const MagickInfo *) NULL)
    {
      if (GetMagickEndianSupport(magick_info) == MagickFalse)
        read_info->endian=UndefinedEndian;
      else
        if ((image_info->endian == UndefinedEndian) &&
            (GetMagickRawSupport(magick_info) != MagickFalse))
          {
            size_t
              lsb_first;

            lsb_first=1;
            read_info->endian=(*(char *) &lsb_first) == 1 ? LSBEndian :
              MSBEndian;
         }
    }
  if ((magick_info != (const MagickInfo *) NULL) &&
      (GetMagickSeekableStream(magick_info) != MagickFalse))
    {
      MagickBooleanType
        status;

      image=AcquireImage(read_info,exception);
      (void) CopyMagickString(image->filename,read_info->filename,
        MaxTextExtent);
      status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
      if (status == MagickFalse)
        {
          read_info=DestroyImageInfo(read_info);
          image=DestroyImage(image);
          return((Image *) NULL);
        }
      if (IsBlobSeekable(image) == MagickFalse)
        {
          /*
            Coder requires a seekable stream.
          */
          *read_info->filename='\0';
          status=ImageToFile(image,read_info->filename,exception);
          if (status == MagickFalse)
            {
              (void) CloseBlob(image);
              read_info=DestroyImageInfo(read_info);
              image=DestroyImage(image);
              return((Image *) NULL);
            }
          read_info->temporary=MagickTrue;
        }
      (void) CloseBlob(image);
      image=DestroyImage(image);
    }
  image=NewImageList();
  if (constitute_semaphore == (SemaphoreInfo *) NULL)
    AcquireSemaphoreInfo(&constitute_semaphore);
  if ((magick_info != (const MagickInfo *) NULL) &&
      (GetImageDecoder(magick_info) != (DecodeImageHandler *) NULL))
    {
      thread_support=GetMagickThreadSupport(magick_info);
      if ((thread_support & DecoderThreadSupport) == 0)
        LockSemaphoreInfo(constitute_semaphore);
      image=GetImageDecoder(magick_info)(read_info,exception);
      if ((thread_support & DecoderThreadSupport) == 0)
        UnlockSemaphoreInfo(constitute_semaphore);
    }
  else
    {
      delegate_info=GetDelegateInfo(read_info->magick,(char *) NULL,exception);
      if (delegate_info == (const DelegateInfo *) NULL)
        {
          (void) ThrowMagickException(exception,GetMagickModule(),
            MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
            read_info->filename);
          if (read_info->temporary != MagickFalse)
            (void) RelinquishUniqueFileResource(read_info->filename);
          read_info=DestroyImageInfo(read_info);
          return((Image *) NULL);
        }
      /*
        Let our decoding delegate process the image.
      */
      image=AcquireImage(read_info,exception);
      if (image == (Image *) NULL)
        {
          read_info=DestroyImageInfo(read_info);
          return((Image *) NULL);
        }
      (void) CopyMagickString(image->filename,read_info->filename,
        MaxTextExtent);
      *read_info->filename='\0';
      if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
        LockSemaphoreInfo(constitute_semaphore);
      (void) InvokeDelegate(read_info,image,read_info->magick,(char *) NULL,
        exception);
      if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
        UnlockSemaphoreInfo(constitute_semaphore);
      image=DestroyImageList(image);
      read_info->temporary=MagickTrue;
      (void) SetImageInfo(read_info,0,exception);
      magick_info=GetMagickInfo(read_info->magick,exception);
      if ((magick_info == (const MagickInfo *) NULL) ||
          (GetImageDecoder(magick_info) == (DecodeImageHandler *) NULL))
        {
          if (IsPathAccessible(read_info->filename) != MagickFalse)
            (void) ThrowMagickException(exception,GetMagickModule(),
              MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
              read_info->filename);
          else
            ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
              read_info->filename);
          read_info=DestroyImageInfo(read_info);
          return((Image *) NULL);
        }
      thread_support=GetMagickThreadSupport(magick_info);
      if ((thread_support & DecoderThreadSupport) == 0)
        LockSemaphoreInfo(constitute_semaphore);
      image=(Image *) (GetImageDecoder(magick_info))(read_info,exception);
      if ((thread_support & DecoderThreadSupport) == 0)
        UnlockSemaphoreInfo(constitute_semaphore);
    }
  if (read_info->temporary != MagickFalse)
    {
      (void) RelinquishUniqueFileResource(read_info->filename);
      read_info->temporary=MagickFalse;
      if (image != (Image *) NULL)
        (void) CopyMagickString(image->filename,filename,MaxTextExtent);
    }
  if (image == (Image *) NULL)
    {
      read_info=DestroyImageInfo(read_info);
      return(image);
    }
  if (exception->severity >= ErrorException)
    (void) LogMagickEvent(ExceptionEvent,GetMagickModule(),
      "Coder (%s) generated an image despite an error (%d), "
      "notify the developers",image->magick,exception->severity);
  if (IsBlobTemporary(image) != MagickFalse)
    (void) RelinquishUniqueFileResource(read_info->filename);
  if ((GetNextImageInList(image) != (Image *) NULL) &&
      (IsSceneGeometry(read_info->scenes,MagickFalse) != MagickFalse))
    {
      Image
        *clones;

      clones=CloneImages(image,read_info->scenes,exception);
      if (clones == (Image *) NULL)
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
          "SubimageSpecificationReturnsNoImages","`%s'",read_info->filename);
      else
        {
          image=DestroyImageList(image);
          image=GetFirstImageInList(clones);
        }
    }
  if (GetBlobError(image) != MagickFalse)
    {
      ThrowFileException(exception,FileOpenError,
        "AnErrorHasOccurredReadingFromFile",read_info->filename);
      image=DestroyImageList(image);
      read_info=DestroyImageInfo(read_info);
      return((Image *) NULL);
    }
  for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
  {
    char
      magick_path[MaxTextExtent],
      *property,
      timestamp[MaxTextExtent];

    const char
      *option;

    const StringInfo
      *profile;

    next->taint=MagickFalse;
    GetPathComponent(magick_filename,MagickPath,magick_path);
    if (*magick_path == '\0')
      (void) CopyMagickString(next->magick,magick,MaxTextExtent);
    (void) CopyMagickString(next->magick_filename,magick_filename,
      MaxTextExtent);
    if (IsBlobTemporary(image) != MagickFalse)
      (void) CopyMagickString(next->filename,filename,MaxTextExtent);
    if (next->magick_columns == 0)
      next->magick_columns=next->columns;
    if (next->magick_rows == 0)
      next->magick_rows=next->rows;
    value=GetImageProperty(next,"tiff:Orientation",exception);
    if (value == (char *) NULL)
      value=GetImageProperty(next,"exif:Orientation",exception);
    if (value != (char *) NULL)
      {
        next->orientation=(OrientationType) StringToLong(value);
        (void) DeleteImageProperty(next,"tiff:Orientation");
        (void) DeleteImageProperty(next,"exif:Orientation");
      }
    value=GetImageProperty(next,"exif:XResolution",exception);
    if (value != (char *) NULL)
      {
        geometry_info.rho=next->resolution.x;
        geometry_info.sigma=1.0;
        flags=ParseGeometry(value,&geometry_info);
        if (geometry_info.sigma != 0)
          next->resolution.x=geometry_info.rho/geometry_info.sigma;
        (void) DeleteImageProperty(next,"exif:XResolution");
      }
    value=GetImageProperty(next,"exif:YResolution",exception);
    if (value != (char *) NULL)
      {
        geometry_info.rho=next->resolution.y;
        geometry_info.sigma=1.0;
        flags=ParseGeometry(value,&geometry_info);
        if (geometry_info.sigma != 0)
          next->resolution.y=geometry_info.rho/geometry_info.sigma;
        (void) DeleteImageProperty(next,"exif:YResolution");
      }
    value=GetImageProperty(next,"tiff:ResolutionUnit",exception);
    if (value == (char *) NULL)
      value=GetImageProperty(next,"exif:ResolutionUnit",exception);
    if (value != (char *) NULL)
      {
        next->units=(ResolutionType) (StringToLong(value)-1);
        (void) DeleteImageProperty(next,"exif:ResolutionUnit");
        (void) DeleteImageProperty(next,"tiff:ResolutionUnit");
      }
    if (next->page.width == 0)
      next->page.width=next->columns;
    if (next->page.height == 0)
      next->page.height=next->rows;
    option=GetImageOption(read_info,"caption");
    if (option != (const char *) NULL)
      {
        property=InterpretImageProperties(read_info,next,option,exception);
        (void) SetImageProperty(next,"caption",property,exception);
        property=DestroyString(property);
      }
    option=GetImageOption(read_info,"comment");
    if (option != (const char *) NULL)
      {
        property=InterpretImageProperties(read_info,next,option,exception);
        (void) SetImageProperty(next,"comment",property,exception);
        property=DestroyString(property);
      }
    option=GetImageOption(read_info,"label");
    if (option != (const char *) NULL)
      {
        property=InterpretImageProperties(read_info,next,option,exception);
        (void) SetImageProperty(next,"label",property,exception);
        property=DestroyString(property);
      }
    if (LocaleCompare(next->magick,"TEXT") == 0)
      (void) ParseAbsoluteGeometry("0x0+0+0",&next->page);
    if ((read_info->extract != (char *) NULL) &&
        (read_info->stream == (StreamHandler) NULL))
      {
        RectangleInfo
          geometry;

        flags=ParseAbsoluteGeometry(read_info->extract,&geometry);
        if ((next->columns != geometry.width) ||
            (next->rows != geometry.height))
          {
            if (((flags & XValue) != 0) || ((flags & YValue) != 0))
              {
                Image
                  *crop_image;

                crop_image=CropImage(next,&geometry,exception);
                if (crop_image != (Image *) NULL)
                  ReplaceImageInList(&next,crop_image);
              }
            else
              if (((flags & WidthValue) != 0) || ((flags & HeightValue) != 0))
                {
                  Image
                    *size_image;

                  flags=ParseRegionGeometry(next,read_info->extract,&geometry,
                    exception);
                  size_image=ResizeImage(next,geometry.width,geometry.height,
                    next->filter,next->blur,exception);
                  if (size_image != (Image *) NULL)
                    ReplaceImageInList(&next,size_image);
                }
          }
      }
    profile=GetImageProfile(next,"icc");
    if (profile == (const StringInfo *) NULL)
      profile=GetImageProfile(next,"icm");
    profile=GetImageProfile(next,"iptc");
    if (profile == (const StringInfo *) NULL)
      profile=GetImageProfile(next,"8bim");
    (void) FormatMagickTime(GetBlobProperties(next)->st_mtime,MaxTextExtent,
      timestamp);
    (void) SetImageProperty(next,"date:modify",timestamp,exception);
    (void) FormatMagickTime(GetBlobProperties(next)->st_ctime,MaxTextExtent,
      timestamp);
    (void) SetImageProperty(next,"date:create",timestamp,exception);
    option=GetImageOption(image_info,"delay");
    if (option != (const char *) NULL)
      {
        GeometryInfo
          geometry_info;

        flags=ParseGeometry(option,&geometry_info);
        if ((flags & GreaterValue) != 0)
          {
            if (next->delay > (size_t) floor(geometry_info.rho+0.5))
              next->delay=(size_t) floor(geometry_info.rho+0.5);
          }
        else
          if ((flags & LessValue) != 0)
            {
              if (next->delay < (size_t) floor(geometry_info.rho+0.5))
                next->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5);
            }
          else
            next->delay=(size_t) floor(geometry_info.rho+0.5);
        if ((flags & SigmaValue) != 0)
          next->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5);
      }
    option=GetImageOption(image_info,"dispose");
    if (option != (const char *) NULL)
      next->dispose=(DisposeType) ParseCommandOption(MagickDisposeOptions,
        MagickFalse,option);
    if (read_info->verbose != MagickFalse)
      (void) IdentifyImage(next,stderr,MagickFalse,exception);
    image=next;
  }
  read_info=DestroyImageInfo(read_info);
  return(GetFirstImageInList(image));
}
Пример #12
0
Image* generate_rendition(Image *const image, ImageInfo const*image_info, char const* spec, char const* rendition_path, ExceptionInfo *exception) {
    unsigned long crop_x;
    unsigned long crop_y;
    unsigned long crop_width;
    unsigned long crop_height;
    unsigned long width;
    unsigned long height;
    unsigned int quality;
    unsigned int resize;
    double blur;
    unsigned int is_progressive;
    Image const* cropped;
    Image *resized;
    RectangleInfo geometry;
    FilterTypes filter;
    ImageInfo *rendition_info;

    if (sscanf(spec, "%lux%lu+%lu+%lu+%lux%lu+%u+%lf+%u+%u", &crop_width, &crop_height, &crop_x, &crop_y, &width, &height, &resize, &blur, &quality, &is_progressive)) {
        if (width > 0 && height > 0) {
            if (crop_width > 0 && crop_height > 0) {
                geometry.x = crop_x;
                geometry.y = crop_y;
                geometry.width = crop_width;
                geometry.height = crop_height;
                cropped = CropImage(image, &geometry, exception);
                if (!cropped) {
                    CatchException(exception);
                    return NULL;
                }
            } else {
                cropped = image;
            }

            filter = get_filter(resize);

            switch (resize) {
            case Sample:
                resized = SampleImage(cropped, width, height, exception);
                break;
            case Scale:
                resized = ScaleImage(cropped, width, height, exception);
                break;
            case Thumbnail:
                resized = ThumbnailImage(cropped, width, height, exception);
                break;
            case Point:
            case Box:
            case Triangle:
            case Hermite:
            case Hanning:
            case Hamming:
            case Blackman:
            case Gaussian:
            case Quadratic:
            case Cubic:
            case Catrom:
            case Mitchell:
            case Lanczos:
            case Bessel:
            case Sinc:
                resized = ResizeImage(cropped, width, height, filter, blur, exception);
                break;
            }

            if (!resized) {
                CatchException(exception);
                return NULL;
            }


            rendition_info = CloneImageInfo(image_info);
            rendition_info->quality = quality;
            strncpy(resized->filename, rendition_path, MaxTextExtent);
            
            if (is_progressive) {
                rendition_info->interlace = LineInterlace;    
                printf("progressive: %s\n", rendition_path);
            }

            if (!WriteImage(rendition_info, resized)) {
                CatchException(exception);
                DestroyImageInfo(rendition_info);
                return NULL;
            }
            printf("wrote %s\n", resized->filename);
            
            DestroyImageInfo(rendition_info);
            return resized;

        }
        
    }

    return NULL;
}
Пример #13
0
HRESULT UITouchButton::Draw(DK_IMAGE drawingImg)
{
	DebugPrintf(DLC_CHENM, "UITouchButton::Draw()  Start");

    if (!m_bIsVisible)
    {
	    DebugPrintf(DLC_CHENM, "UITouchButton::Draw()  End: m_bIsVisible = false");
        return S_OK;
    }

    if (drawingImg.pbData == NULL)
    {
	    DebugPrintf(DLC_CHENM, "UITouchButton::Draw()  End: m_bIsVisible = false");
        return E_FAIL;
    }

    HRESULT hr(S_OK);
    DK_IMAGE imgSelf;
    DK_RECT rcSelf={m_iLeft, m_iTop, m_iLeft + m_iWidth, m_iTop + m_iHeight};
    RTN_HR_IF_FAILED(CropImage(
                            drawingImg,
                            rcSelf,
                            &imgSelf
                            ));

    CTpGraphics grf(imgSelf);


    if (m_bUsingBackgroundPicture)
    {
        // draw background picture if there is
        if (IsFocus() || IsPressed())
        {
            if (m_spFocusedBackground)
            {
                    HRESULT hr(S_OK);
	                DebugPrintf(DLC_CHENM, "UITouchButton::Draw()  Draw background Image  in focus");
                    int startx = (m_iWidth - m_spFocusedBackground.Get()->GetWidth());

                    if (startx >0)
                        startx = startx / 2;
                    else
                        startx =0;

                    int starty = (m_iHeight - m_spFocusedBackground.Get()->GetHeight());

                    if (starty >0)
                        starty = starty / 2;
                    else
                        starty =0;

                    RTN_HR_IF_FAILED(grf.DrawImage(m_spFocusedBackground.Get(),startx,starty,0,0,m_spFocusedBackground.Get()->GetWidth(), m_spFocusedBackground.Get()->GetHeight()));
                    //RTN_HR_IF_FAILED(grf.DrawImage(m_spFocusedBackground.Get(), 0, 0));
            }
        }
        else
        {
            if (m_spBackground)
            {
	                DebugPrintf(DLC_CHENM, "UITouchButton::Draw()  Draw background Image not in focus");

                    int startx = (m_iWidth - m_spBackground.Get()->GetWidth());

                    if (startx >0)
                        startx = startx / 2;
                    else
                        startx =0;

                    int starty = (m_iHeight - m_spBackground.Get()->GetHeight());

                    if (starty >0)
                        starty = starty / 2;
                    else
                        starty =0;

                    HRESULT hr(S_OK);
                    RTN_HR_IF_FAILED(grf.DrawImage(m_spBackground.Get(), startx, starty, 0, 0, m_spBackground.Get()->GetWidth(), m_spBackground.Get()->GetHeight()));
                    //RTN_HR_IF_FAILED(grf.DrawImage(m_spBackground.Get(), 0, 0));
            }
        }
    }
    else
    {
        // draw background in color
        if (!m_bBackTransparent)
        {
            if (IsFocus() || IsPressed())
            {
	            DebugPrintf(DLC_CHENM, "UITouchButton::Draw()  Draw background with color in focus");
                RTN_HR_IF_FAILED(grf.FillRect(
                    0,
                    0,
                    m_iWidth,
                    m_iHeight,
                    m_focusedBackgroundColor));
            }
            else
            {
	            DebugPrintf(DLC_CHENM, "UITouchButton::Draw()  Draw background with color not in focus");
                RTN_HR_IF_FAILED(grf.FillRect(
                    0,
                    0,
                    m_iWidth,
                    m_iHeight,
                    GetBackgroundColor()));
            }
        }
    }
    //draw string
    if (m_strText.Length() > 0)
    {
        m_ifontAttr.m_iFace=FONT_DEFAULT;
        
        ITpFont* pFont = NULL;

        if (IsFocus() || IsPressed())
        {
            pFont = FontManager::GetInstance()->GetFont(m_ifontAttr, m_iFocusedFontColor);
        }
        else
        {
            pFont = FontManager::GetInstance()->GetFont(m_ifontAttr, GetFontColor());
        }

        if(NULL == pFont)
        {
	        DebugPrintf(DLC_CHENM, "UITouchButton::Draw()  End: pFont = NULL");
            return E_FAIL;
        }

        int _iStringWidth = pFont->StringWidth(m_strText);
        int _iStringHeight = pFont->GetHeight();

        if (_iStringWidth > m_iWidth)
        {
	        DebugPrintf(DLC_CHENM, "UITouchButton::Draw()  End:_iStringWidth > m_iWidth");
            return E_FAIL;
        }

        int _H_offset = (m_iWidth - _iStringWidth) / 2;
        int _V_offset = (m_iHeight - _iStringHeight) / 2;

        grf.DrawStringUtf8(m_strText.GetBuffer(), _H_offset, _V_offset, pFont);
    }

    if (m_do2gray)
    {
        grf.Do2Gray(0,0,m_iWidth, m_iHeight, 80, FALSE, (IsEnable() ? 0xff : 0x66));
    }

    DebugPrintf(DLC_CHENM, "UITouchButton::Draw()  End.");
    return hr;
}
Пример #14
0
WandExport MagickBooleanType CompareImageCommand(ImageInfo *image_info,
  int argc,char **argv,char **metadata,ExceptionInfo *exception)
{
#define CompareEpsilon  (1.0e-06)
#define DefaultDissimilarityThreshold  0.31830988618379067154
#define DefaultSimilarityThreshold  (-1.0)
#define DestroyCompare() \
{ \
  if (similarity_image != (Image *) NULL) \
    similarity_image=DestroyImageList(similarity_image); \
  if (difference_image != (Image *) NULL) \
    difference_image=DestroyImageList(difference_image); \
  DestroyImageStack(); \
  for (i=0; i < (ssize_t) argc; i++) \
    argv[i]=DestroyString(argv[i]); \
  argv=(char **) RelinquishMagickMemory(argv); \
}
#define ThrowCompareException(asperity,tag,option) \
{ \
  if (exception->severity < (asperity)) \
    (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag, \
      "`%s'",option); \
  DestroyCompare(); \
  return(MagickFalse); \
}
#define ThrowCompareInvalidArgumentException(option,argument) \
{ \
  (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
    "InvalidArgument","`%s': %s",option,argument); \
  DestroyCompare(); \
  return(MagickFalse); \
}

  char
    *filename,
    *option;

  const char
    *format;

  ChannelType
    channels;

  double
    dissimilarity_threshold,
    distortion,
    similarity_metric,
    similarity_threshold;

  Image
    *difference_image,
    *image,
    *reconstruct_image,
    *similarity_image;

  ImageInfo
    *restore_info;

  ImageStack
    image_stack[MaxImageStackDepth+1];

  MagickBooleanType
    fire,
    pend,
    respect_parenthesis,
    subimage_search;

  MagickStatusType
    status;

  MetricType
    metric;

  RectangleInfo
    offset;

  register ssize_t
    i;

  ssize_t
    j,
    k;

  /*
    Set defaults.
  */
  assert(image_info != (ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  assert(exception != (ExceptionInfo *) NULL);
  if (argc == 2)
    {
      option=argv[1];
      if ((LocaleCompare("version",option+1) == 0) ||
          (LocaleCompare("-version",option+1) == 0))
        {
          ListMagickVersion(stdout);
          return(MagickFalse);
        }
    }
  if (argc < 3)
    return(CompareUsage());
  restore_info=image_info;
  channels=CompositeChannels;
  difference_image=NewImageList();
  similarity_image=NewImageList();
  dissimilarity_threshold=DefaultDissimilarityThreshold;
  similarity_threshold=DefaultSimilarityThreshold;
  distortion=0.0;
  format=(char *) NULL;
  j=1;
  k=0;
  metric=UndefinedErrorMetric;
  NewImageStack();
  option=(char *) NULL;
  pend=MagickFalse;
  reconstruct_image=NewImageList();
  respect_parenthesis=MagickFalse;
  status=MagickTrue;
  subimage_search=MagickFalse;
  /*
    Compare an image.
  */
  ReadCommandlLine(argc,&argv);
  status=ExpandFilenames(&argc,&argv);
  if (status == MagickFalse)
    ThrowCompareException(ResourceLimitError,"MemoryAllocationFailed",
      GetExceptionMessage(errno));
  for (i=1; i < (ssize_t) (argc-1); i++)
  {
    option=argv[i];
    if (LocaleCompare(option,"(") == 0)
      {
        FireImageStack(MagickTrue,MagickTrue,pend);
        if (k == MaxImageStackDepth)
          ThrowCompareException(OptionError,"ParenthesisNestedTooDeeply",
            option);
        PushImageStack();
        continue;
      }
    if (LocaleCompare(option,")") == 0)
      {
        FireImageStack(MagickTrue,MagickTrue,MagickTrue);
        if (k == 0)
          ThrowCompareException(OptionError,"UnableToParseExpression",option);
        PopImageStack();
        continue;
      }
    if (IsCommandOption(option) == MagickFalse)
      {
        Image
          *images;

        /*
          Read input image.
        */
        FireImageStack(MagickFalse,MagickFalse,pend);
        filename=argv[i];
        if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1)))
          filename=argv[++i];
        (void) SetImageOption(image_info,"filename",filename);
        (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
        images=ReadImages(image_info,exception);
        status&=(images != (Image *) NULL) &&
          (exception->severity < ErrorException);
        if (images == (Image *) NULL)
          continue;
        AppendImageStack(images);
        continue;
      }
    pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
    switch (*(option+1))
    {
      case 'a':
      {
        if (LocaleCompare("alpha",option+1) == 0)
          {
            ssize_t
              type;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            type=ParseCommandOption(MagickAlphaOptions,MagickFalse,argv[i]);
            if (type < 0)
              ThrowCompareException(OptionError,"UnrecognizedAlphaChannelType",
                argv[i]);
            break;
          }
        if (LocaleCompare("authenticate",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            break;
          }
        ThrowCompareException(OptionError,"UnrecognizedOption",option);
      }
      case 'c':
      {
        if (LocaleCompare("cache",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("channel",option+1) == 0)
          {
            ssize_t
              channel;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            channel=ParseChannelOption(argv[i]);
            if (channel < 0)
              ThrowCompareException(OptionError,"UnrecognizedChannelType",
                argv[i]);
            channels=(ChannelType) channel;
            break;
          }
        if (LocaleCompare("colorspace",option+1) == 0)
          {
            ssize_t
              colorspace;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            colorspace=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
              argv[i]);
            if (colorspace < 0)
              ThrowCompareException(OptionError,"UnrecognizedColorspace",
                argv[i]);
            break;
          }
        if (LocaleCompare("compose",option+1) == 0)
          {
            ssize_t
              compose;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            compose=ParseCommandOption(MagickComposeOptions,MagickFalse,
              argv[i]);
            if (compose < 0)
              ThrowCompareException(OptionError,"UnrecognizedComposeOperator",
                argv[i]);
            break;
          }
        if (LocaleCompare("compress",option+1) == 0)
          {
            ssize_t
              compress;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            compress=ParseCommandOption(MagickCompressOptions,MagickFalse,
              argv[i]);
            if (compress < 0)
              ThrowCompareException(OptionError,"UnrecognizedImageCompression",
                argv[i]);
            break;
          }
        if (LocaleCompare("concurrent",option+1) == 0)
          break;
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 'd':
      {
        if (LocaleCompare("debug",option+1) == 0)
          {
            LogEventType
              event_mask;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            event_mask=SetLogEventMask(argv[i]);
            if (event_mask == UndefinedEvents)
              ThrowCompareException(OptionError,"UnrecognizedEventType",
                argv[i]);
            break;
          }
        if (LocaleCompare("decipher",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("define",option+1) == 0)
          {
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (*option == '+')
              {
                const char
                  *define;

                define=GetImageOption(image_info,argv[i]);
                if (define == (const char *) NULL)
                  ThrowCompareException(OptionError,"NoSuchOption",argv[i]);
                break;
              }
            break;
          }
        if (LocaleCompare("density",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("depth",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("dissimilarity-threshold",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            if (*option == '+')
              dissimilarity_threshold=DefaultDissimilarityThreshold;
            else
              dissimilarity_threshold=StringToDouble(argv[i],(char **) NULL);
            break;
          }
        if (LocaleCompare("duration",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            break;
          }
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 'e':
      {
        if (LocaleCompare("encipher",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("extract",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            break;
          }
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 'f':
      {
        if (LocaleCompare("format",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            format=argv[i];
            break;
          }
        if (LocaleCompare("fuzz",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            break;
          }
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 'h':
      {
        if ((LocaleCompare("help",option+1) == 0) ||
            (LocaleCompare("-help",option+1) == 0))
          return(CompareUsage());
        if (LocaleCompare("highlight-color",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            break;
          }
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 'i':
      {
        if (LocaleCompare("identify",option+1) == 0)
          break;
        if (LocaleCompare("interlace",option+1) == 0)
          {
            ssize_t
              interlace;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
              argv[i]);
            if (interlace < 0)
              ThrowCompareException(OptionError,"UnrecognizedInterlaceType",
                argv[i]);
            break;
          }
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 'l':
      {
        if (LocaleCompare("limit",option+1) == 0)
          {
            char
              *p;

            double
              value;

            ssize_t
              resource;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
              argv[i]);
            if (resource < 0)
              ThrowCompareException(OptionError,"UnrecognizedResourceType",
                argv[i]);
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            value=StringToDouble(argv[i],&p);
            (void) value;
            if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
              ThrowCompareInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("list",option+1) == 0)
          {
            ssize_t
              list;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
            if (list < 0)
              ThrowCompareException(OptionError,"UnrecognizedListType",argv[i]);
            status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
              argv+j,exception);
            DestroyCompare();
            return(status != 0 ? MagickFalse : MagickTrue);
          }
        if (LocaleCompare("log",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL))
              ThrowCompareException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("lowlight-color",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            break;
          }
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 'm':
      {
        if (LocaleCompare("matte",option+1) == 0)
          break;
        if (LocaleCompare("metric",option+1) == 0)
          {
            ssize_t
              type;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            type=ParseCommandOption(MagickMetricOptions,MagickTrue,argv[i]);
            if (type < 0)
              ThrowCompareException(OptionError,"UnrecognizedMetricType",
                argv[i]);
            metric=(MetricType) type;
            break;
          }
        if (LocaleCompare("monitor",option+1) == 0)
          break;
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 'p':
      {
        if (LocaleCompare("passphrase",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("profile",option+1) == 0)
          {
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            break;
          }
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 'q':
      {
        if (LocaleCompare("quality",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("quantize",option+1) == 0)
          {
            ssize_t
              colorspace;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            colorspace=ParseCommandOption(MagickColorspaceOptions,
              MagickFalse,argv[i]);
            if (colorspace < 0)
              ThrowCompareException(OptionError,"UnrecognizedColorspace",
                argv[i]);
            break;
          }
        if (LocaleCompare("quiet",option+1) == 0)
          break;
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 'r':
      {
        if (LocaleCompare("regard-warnings",option+1) == 0)
          break;
        if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
          {
            respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
            break;
          }
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 's':
      {
        if (LocaleCompare("sampling-factor",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("seed",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("set",option+1) == 0)
          {
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("similarity-threshold",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            if (*option == '+')
              similarity_threshold=DefaultSimilarityThreshold;
            else
              similarity_threshold=StringToDouble(argv[i],(char **) NULL);
            break;
          }
        if (LocaleCompare("size",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowCompareInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("subimage-search",option+1) == 0)
          {
            if (*option == '+')
              {
                subimage_search=MagickFalse;
                break;
              }
            subimage_search=MagickTrue;
            break;
          }
        if (LocaleCompare("synchronize",option+1) == 0)
          break;
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 't':
      {
        if (LocaleCompare("taint",option+1) == 0)
          break;
        if (LocaleCompare("transparent-color",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("type",option+1) == 0)
          {
            ssize_t
              type;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowCompareException(OptionError,"MissingArgument",option);
            type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]);
            if (type < 0)
              ThrowCompareException(OptionError,"UnrecognizedImageType",
                argv[i]);
            break;
          }
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case 'v':
      {
        if (LocaleCompare("verbose",option+1) == 0)
          break;
        if ((LocaleCompare("version",option+1) == 0) ||
            (LocaleCompare("-version",option+1) == 0))
          {
            ListMagickVersion(stdout);
            break;
          }
        if (LocaleCompare("virtual-pixel",option+1) == 0)
          {
            ssize_t
              method;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowCompareException(OptionError,"MissingArgument",option);
            method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
              argv[i]);
            if (method < 0)
              ThrowCompareException(OptionError,
                "UnrecognizedVirtualPixelMethod",argv[i]);
            break;
          }
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
      }
      case '?':
        break;
      default:
        ThrowCompareException(OptionError,"UnrecognizedOption",option)
    }
    fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
      FireOptionFlag) == 0 ?  MagickFalse : MagickTrue;
    if (fire != MagickFalse)
      FireImageStack(MagickTrue,MagickTrue,MagickTrue);
  }
  if (k != 0)
    ThrowCompareException(OptionError,"UnbalancedParenthesis",argv[i]);
  if (i-- != (ssize_t) (argc-1))
    ThrowCompareException(OptionError,"MissingAnImageFilename",argv[i]);
  if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
    ThrowCompareException(OptionError,"MissingAnImageFilename",argv[i]);
  FinalizeImageSettings(image_info,image,MagickTrue);
  if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
    ThrowCompareException(OptionError,"MissingAnImageFilename",argv[i]);
  image=GetImageFromList(image,0);
  reconstruct_image=GetImageFromList(image,1);
  offset.x=0;
  offset.y=0;
  if (subimage_search != MagickFalse)
    {
      char
        artifact[MaxTextExtent];

      (void) FormatLocaleString(artifact,MaxTextExtent,"%g",
        similarity_threshold);
      (void) SetImageArtifact(image,"compare:similarity-threshold",artifact);
      similarity_image=SimilarityMetricImage(image,reconstruct_image,metric,
        &offset,&similarity_metric,exception);
      if (similarity_metric > dissimilarity_threshold)
        ThrowCompareException(ImageError,"ImagesTooDissimilar",image->filename);
    }
  if ((reconstruct_image->columns == image->columns) &&
      (reconstruct_image->rows == image->rows))
    difference_image=CompareImageChannels(image,reconstruct_image,channels,
      metric,&distortion,exception);
  else
    if (similarity_image == (Image *) NULL)
      {
        unsigned long
          height,
          width;

        width=image->columns;
        if (reconstruct_image->columns > width)
          width=reconstruct_image->columns;
        height=image->rows;
        if (reconstruct_image->rows > height)
          height=reconstruct_image->rows;
        if ((SetImageExtent(image,width,height) != MagickFalse) &&
            (SetImageExtent(reconstruct_image,width,height) != MagickFalse))
          difference_image=CompareImageChannels(image,reconstruct_image,
            channels,metric,&distortion,exception);
      }
    else
      {
        Image
          *composite_image;

        /*
          Determine if reconstructed image is a subimage of the image.
        */
        composite_image=CloneImage(image,0,0,MagickTrue,exception);
        if (composite_image == (Image *) NULL)
          difference_image=CompareImageChannels(image,reconstruct_image,
            channels,metric,&distortion,exception);
        else
          {
            Image
              *distort_image;

            RectangleInfo
              page;

            (void) CompositeImage(composite_image,CopyCompositeOp,
              reconstruct_image,offset.x,offset.y);
            difference_image=CompareImageChannels(image,composite_image,
              channels,metric,&distortion,exception);
            if (difference_image != (Image *) NULL)
              {
                difference_image->page.x=offset.x;
                difference_image->page.y=offset.y;
              }
            composite_image=DestroyImage(composite_image);
            page.width=reconstruct_image->columns;
            page.height=reconstruct_image->rows;
            page.x=offset.x;
            page.y=offset.y;
            distort_image=CropImage(image,&page,exception);
            if (distort_image != (Image *) NULL)
              {
                Image
                  *sans_image;

                sans_image=CompareImageChannels(distort_image,reconstruct_image,
                  channels,metric,&distortion,exception);
                distort_image=DestroyImage(distort_image);
                if (sans_image != (Image *) NULL)
                  sans_image=DestroyImage(sans_image);
              }
          }
        if (difference_image != (Image *) NULL)
          {
            AppendImageToList(&difference_image,similarity_image);
            similarity_image=(Image *) NULL;
          }
      }
  if (difference_image == (Image *) NULL)
    status=0;
  else
    {
      if (image_info->verbose != MagickFalse)
        (void) IsImagesEqual(image,reconstruct_image);
      if (*difference_image->magick == '\0')
        (void) CopyMagickString(difference_image->magick,image->magick,
          MaxTextExtent);
      if (image_info->verbose == MagickFalse)
        {
          switch (metric)
          {
            case FuzzErrorMetric:
            case MeanAbsoluteErrorMetric:
            case MeanSquaredErrorMetric:
            case PeakAbsoluteErrorMetric:
            case RootMeanSquaredErrorMetric:
            {
              (void) FormatLocaleFile(stderr,"%g (%g)",QuantumRange*distortion,
                (double) distortion);
              if ((reconstruct_image->columns != image->columns) ||
                  (reconstruct_image->rows != image->rows))
                (void) FormatLocaleFile(stderr," @ %.20g,%.20g",(double)
                  difference_image->page.x,(double) difference_image->page.y);
              break;
            }
            case AbsoluteErrorMetric:
            case NormalizedCrossCorrelationErrorMetric:
            case PeakSignalToNoiseRatioMetric:
            case PerceptualHashErrorMetric:
            {
              (void) FormatLocaleFile(stderr,"%g",distortion);
              if ((reconstruct_image->columns != image->columns) ||
                  (reconstruct_image->rows != image->rows))
                (void) FormatLocaleFile(stderr," @ %.20g,%.20g",(double)
                  difference_image->page.x,(double) difference_image->page.y);
              break;
            }
            case MeanErrorPerPixelMetric:
            {
              (void) FormatLocaleFile(stderr,"%g (%g, %g)",distortion,
                image->error.normalized_mean_error,
                image->error.normalized_maximum_error);
              if ((reconstruct_image->columns != image->columns) ||
                  (reconstruct_image->rows != image->rows))
                (void) FormatLocaleFile(stderr," @ %.20g,%.20g",(double)
                  difference_image->page.x,(double) difference_image->page.y);
              break;
            }
            case UndefinedErrorMetric:
              break;
          }
        }
      else
        {
          double
            *channel_distortion;

          channel_distortion=GetImageChannelDistortions(image,reconstruct_image,
            metric,&image->exception);
          (void) FormatLocaleFile(stderr,"Image: %s\n",image->filename);
          if ((reconstruct_image->columns != image->columns) ||
              (reconstruct_image->rows != image->rows))
            (void) FormatLocaleFile(stderr,"Offset: %.20g,%.20g\n",(double)
              difference_image->page.x,(double) difference_image->page.y);
          (void) FormatLocaleFile(stderr,"  Channel distortion: %s\n",
            CommandOptionToMnemonic(MagickMetricOptions,(ssize_t) metric));
          switch (metric)
          {
            case FuzzErrorMetric:
            case MeanAbsoluteErrorMetric:
            case MeanSquaredErrorMetric:
            case PeakAbsoluteErrorMetric:
            case RootMeanSquaredErrorMetric:
            {
              switch (image->colorspace)
              {
                case RGBColorspace:
                default:
                {
                  (void) FormatLocaleFile(stderr,"    red: %g (%g)\n",
                    QuantumRange*channel_distortion[RedChannel],
                    channel_distortion[RedChannel]);
                  (void) FormatLocaleFile(stderr,"    green: %g (%g)\n",
                    QuantumRange*channel_distortion[GreenChannel],
                    channel_distortion[GreenChannel]);
                  (void) FormatLocaleFile(stderr,"    blue: %g (%g)\n",
                    QuantumRange*channel_distortion[BlueChannel],
                    channel_distortion[BlueChannel]);
                  if (image->matte != MagickFalse)
                    (void) FormatLocaleFile(stderr,"    alpha: %g (%g)\n",
                      QuantumRange*channel_distortion[OpacityChannel],
                      channel_distortion[OpacityChannel]);
                  break;
                }
                case CMYKColorspace:
                {
                  (void) FormatLocaleFile(stderr,"    cyan: %g (%g)\n",
                    QuantumRange*channel_distortion[CyanChannel],
                    channel_distortion[CyanChannel]);
                  (void) FormatLocaleFile(stderr,"    magenta: %g (%g)\n",
                    QuantumRange*channel_distortion[MagentaChannel],
                    channel_distortion[MagentaChannel]);
                  (void) FormatLocaleFile(stderr,"    yellow: %g (%g)\n",
                    QuantumRange*channel_distortion[YellowChannel],
                    channel_distortion[YellowChannel]);
                  (void) FormatLocaleFile(stderr,"    black: %g (%g)\n",
                    QuantumRange*channel_distortion[BlackChannel],
                    channel_distortion[BlackChannel]);
                  if (image->matte != MagickFalse)
                    (void) FormatLocaleFile(stderr,"    alpha: %g (%g)\n",
                      QuantumRange*channel_distortion[OpacityChannel],
                      channel_distortion[OpacityChannel]);
                  break;
                }
                case GRAYColorspace:
                {
                  (void) FormatLocaleFile(stderr,"    gray: %g (%g)\n",
                    QuantumRange*channel_distortion[GrayChannel],
                    channel_distortion[GrayChannel]);
                  if (image->matte != MagickFalse)
                    (void) FormatLocaleFile(stderr,"    alpha: %g (%g)\n",
                      QuantumRange*channel_distortion[OpacityChannel],
                      channel_distortion[OpacityChannel]);
                  break;
                }
              }
              (void) FormatLocaleFile(stderr,"    all: %g (%g)\n",
                QuantumRange*channel_distortion[CompositeChannels],
                channel_distortion[CompositeChannels]);
              break;
            }
            case AbsoluteErrorMetric:
            case NormalizedCrossCorrelationErrorMetric:
            case PeakSignalToNoiseRatioMetric:
            case PerceptualHashErrorMetric:
            {
              switch (image->colorspace)
              {
                case RGBColorspace:
                default:
                {
                  (void) FormatLocaleFile(stderr,"    red: %g\n",
                    channel_distortion[RedChannel]);
                  (void) FormatLocaleFile(stderr,"    green: %g\n",
                    channel_distortion[GreenChannel]);
                  (void) FormatLocaleFile(stderr,"    blue: %g\n",
                    channel_distortion[BlueChannel]);
                  if (image->matte != MagickFalse)
                    (void) FormatLocaleFile(stderr,"    alpha: %g\n",
                      channel_distortion[OpacityChannel]);
                  break;
                }
                case CMYKColorspace:
                {
                  (void) FormatLocaleFile(stderr,"    cyan: %g\n",
                    channel_distortion[CyanChannel]);
                  (void) FormatLocaleFile(stderr,"    magenta: %g\n",
                    channel_distortion[MagentaChannel]);
                  (void) FormatLocaleFile(stderr,"    yellow: %g\n",
                    channel_distortion[YellowChannel]);
                  (void) FormatLocaleFile(stderr,"    black: %g\n",
                    channel_distortion[BlackChannel]);
                  if (image->matte != MagickFalse)
                    (void) FormatLocaleFile(stderr,"    alpha: %g\n",
                      channel_distortion[OpacityChannel]);
                  break;
                }
                case GRAYColorspace:
                {
                  (void) FormatLocaleFile(stderr,"    gray: %g\n",
                    channel_distortion[GrayChannel]);
                  if (image->matte != MagickFalse)
                    (void) FormatLocaleFile(stderr,"    alpha: %g\n",
                      channel_distortion[OpacityChannel]);
                  break;
                }
              }
              (void) FormatLocaleFile(stderr,"    all: %g\n",
                channel_distortion[CompositeChannels]);
              break;
            }
            case MeanErrorPerPixelMetric:
            {
              (void) FormatLocaleFile(stderr,"    %g (%g, %g)\n",
                channel_distortion[CompositeChannels],
                image->error.normalized_mean_error,
                image->error.normalized_maximum_error);
              break;
            }
            case UndefinedErrorMetric:
              break;
          }
          channel_distortion=(double *) RelinquishMagickMemory(
            channel_distortion);
        }
      status&=WriteImages(image_info,difference_image,argv[argc-1],exception);
      if ((metadata != (char **) NULL) && (format != (char *) NULL))
        {
          char
            *text;

          text=InterpretImageProperties(image_info,difference_image,format);
          if (text == (char *) NULL)
            ThrowCompareException(ResourceLimitError,"MemoryAllocationFailed",
              GetExceptionMessage(errno));
          (void) ConcatenateString(&(*metadata),text);
          text=DestroyString(text);
        }
      difference_image=DestroyImageList(difference_image);
    }
  DestroyCompare();
  image_info=restore_info;
  if ((metric == NormalizedCrossCorrelationErrorMetric) ||
      (metric == UndefinedErrorMetric))
    {
      if (fabs(distortion-1.0) > CompareEpsilon)
        (void) SetImageOption(image_info,"compare:dissimilar","true");
    }
  else
    if (fabs(distortion) > CompareEpsilon)
      (void) SetImageOption(image_info,"compare:dissimilar","true");
  return(status != 0 ? MagickTrue : MagickFalse);
}
Пример #15
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   C r o p T o F i t I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  CropToFitImage() crops the sheared image as determined by the bounding box
%  as defined by width and height and shearing angles.
%
%  The format of the CropToFitImage method is:
%
%      Image *CropToFitImage(Image **image,const MagickRealType x_shear,
%        const MagickRealType x_shear,const MagickRealType width,
%        const MagickRealType height,const MagickBooleanType rotate,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows.
%
%    o image: the image.
%
%    o x_shear, y_shear, width, height: Defines a region of the image to crop.
%
%    o exception: Return any errors or warnings in this structure.
%
*/
static inline void CropToFitImage(Image **image,const MagickRealType x_shear,
  const MagickRealType y_shear,const MagickRealType width,
  const MagickRealType height,const MagickBooleanType rotate,
  ExceptionInfo *exception)
{
  Image
    *crop_image;

  PointInfo
    extent[4],
    min,
    max;

  RectangleInfo
    geometry,
    page;

  register long
    i;

  /*
    Calculate the rotated image size.
  */
  extent[0].x=(double) (-width/2.0);
  extent[0].y=(double) (-height/2.0);
  extent[1].x=(double) width/2.0;
  extent[1].y=(double) (-height/2.0);
  extent[2].x=(double) (-width/2.0);
  extent[2].y=(double) height/2.0;
  extent[3].x=(double) width/2.0;
  extent[3].y=(double) height/2.0;
  for (i=0; i < 4; i++)
  {
    extent[i].x+=x_shear*extent[i].y;
    extent[i].y+=y_shear*extent[i].x;
    if (rotate != MagickFalse)
      extent[i].x+=x_shear*extent[i].y;
    extent[i].x+=(double) (*image)->columns/2.0;
    extent[i].y+=(double) (*image)->rows/2.0;
  }
  min=extent[0];
  max=extent[0];
  for (i=1; i < 4; i++)
  {
    if (min.x > extent[i].x)
      min.x=extent[i].x;
    if (min.y > extent[i].y)
      min.y=extent[i].y;
    if (max.x < extent[i].x)
      max.x=extent[i].x;
    if (max.y < extent[i].y)
      max.y=extent[i].y;
  }
  geometry.x=(long) (min.x+0.5);
  geometry.y=(long) (min.y+0.5);
  geometry.width=(unsigned long) ((long) (max.x+0.5)-(long) (min.x+0.5));
  geometry.height=(unsigned long) ((long) (max.y+0.5)-(long) (min.y+0.5));
  page=(*image)->page;
  (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
  crop_image=CropImage(*image,&geometry,exception);
  (*image)->page=page;
  if (crop_image != (Image *) NULL)
    {
      crop_image->page=page;
      *image=DestroyImage(*image);
      *image=crop_image;
    }
}
Пример #16
0
int InitMachine(void)
{
  int J;

  /* Initialize variables */
  UseZoom       = UseZoom<1? 1:UseZoom>5? 5:UseZoom;
  InMenu        = 0;
  FastForward   = 0;
  OutImage.Data = 0;
  KeyReady      = 0;

  /* Initialize system resources */
  if (!InitQNX(Title,UseZoom*WIDTH,UseZoom*HEIGHT))
	  return 0;

  /* Set visual effects */
  BPSSetEffects(UseEffects);

  /* Create main image buffer */
  if(!NewImage(&OutImage,WIDTH,HEIGHT)) { TrashQNX(); return(0); }
  ClearImage(&OutImage,PIXEL(0,0,0));
  CropImage(&ScrImage,&OutImage,XOFFSET,YOFFSET,(TI83_FAMILY?5:4)*TIWIDTH,4*TIHEIGHT);

  /* Initialize video to main image */
  SetVideo(&OutImage,0,0,WIDTH,HEIGHT);

  /* Set colors */
  XPal[0] = White = PIXEL(255,255,255);
  XPal[1] = Black = PIXEL(0,0,0);

  /* Attach keyboard handler */
  SetKeyHandler(HandleKeys);

  /* Attach mouse handler */
  SetMouseHandler(HandleMouse);

  /* Initialize sound */
  InitSound(UseSound,150);
  SndSwitch=(1<<4)-1;
  SndVolume=255/4;
  SetChannels(SndVolume,SndSwitch);

  /* Initialize sync timer if needed */
  if((SyncFreq>0)&&!SetSyncTimer(SyncFreq*UPeriod/100)) SyncFreq=0;

	deviceinfo_details_t* data;
	deviceinfo_get_details(&data);
	const char* os = deviceinfo_details_get_device_os(data);

	if (strcmp(os, "BlackBerry 10") == 0)
	{
		int i = 0;
		while (TouchMap[i].KeyCode)
		{
			TouchMap[i].X = TouchMap[i].X * 1.28;
			TouchMap[i].W = TouchMap[i].W * 1.28;
			TouchMap[i].Y = TouchMap[i].Y * 1.25;
			TouchMap[i].H = TouchMap[i].H * 1.25;
			i++;
		}
	}

	deviceinfo_free_details(&data);

  /* Done */
  return(1);
}
ngx_int_t
convert_image(ngx_http_request_t *r, convert_options_t *option_info,
    Image **image)
{
    ngx_uint_t                          i;

    ngx_http_gm_convert_option_t      *options;
    ngx_http_gm_convert_option_t      *option;

    RectangleInfo                      geometry;
    RectangleInfo                      geometry_info;
    ExceptionInfo                      exception;

    Image                             *resize_image = NULL;
    u_char                            *resize_geometry = NULL;
    u_char                            *need_crop_resize = NULL;

    Image                             *rotate_image = NULL;
    u_char                            *rotate_degrees = NULL;
    ngx_int_t                          degrees;
    ngx_int_t                          degrees_suffix_len = 0;

    dd("entering");

    options = option_info->options->elts;

    for (i = 0; i < option_info->options->nelts; ++i) {
        option = &options[i];

        if (option->type == NGX_HTTP_GM_RESIZE_OPTION) {
            dd("starting resize");

            resize_geometry = ngx_http_gm_get_str_value(r,
                    option->resize_geometry_cv, &option->resize_geometry);

            need_crop_resize = (u_char *)ngx_strchr(resize_geometry, 'c');
            if (need_crop_resize != NULL) {
                *need_crop_resize = '^';
            }

            if (resize_geometry == NULL) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                        "gm filter: resize image, get resize geometry failed");
                return  NGX_ERROR;
            }

            if (ngx_strncmp(resize_geometry, "no", 2) == 0) {
                continue;
            }


            (void) GetImageGeometry(*image, (char *)resize_geometry, 1,
                                    &geometry);

            if ((geometry.width == (*image)->columns) &&
                (geometry.height == (*image)->rows))
                continue;

            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "resize image geometry: \"%s\"", resize_geometry);

            GetExceptionInfo(&exception);
            resize_image = ResizeImage(*image, geometry.width, geometry.height,
                (*image)->filter,(*image)->blur, &exception);

            if (resize_image == (Image *) NULL) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                              "gm filter: resize image failed, "
                              "arg: \"%s\" severity: \"%O\" "
                              "reason: \"%s\", description: \"%s\"",
                              resize_geometry, exception.severity,
                              exception.reason, exception.description);

                DestroyExceptionInfo(&exception);

                return NGX_ERROR;
            }

            DestroyImage(*image);
            *image = resize_image;
            DestroyExceptionInfo(&exception);

            if (need_crop_resize != NULL) {
                GetGeometry((char *)resize_geometry,
                            &geometry_info.x, &geometry_info.y,
                            (unsigned long *)(&geometry_info.width),
                            (unsigned long *)(&geometry_info.height));

                if (geometry_info.width > (*image)->columns ||
                        geometry_info.height > (*image)->rows) {
                    continue;
                }

                geometry_info.x = ((*image)->columns - geometry_info.width) / 2;
                geometry_info.y = ((*image)->rows - geometry_info.height) / 2;

                GetExceptionInfo(&exception);
                resize_image = CropImage(*image, &geometry_info, &exception);


                if (resize_image == (Image *) NULL) {
                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                                "gm filter: resize croping image failed, "
                                "arg: \"%s\" severity: \"%O\" "
                                "reason: \"%s\", description: \"%s\"",
                                resize_geometry, exception.severity,
                                exception.reason, exception.description);

                    DestroyExceptionInfo(&exception);

                    return NGX_ERROR;
                }

                DestroyImage(*image);
                *image = resize_image;
                DestroyExceptionInfo(&exception);
            }

        } else if (option->type == NGX_HTTP_GM_ROTATE_OPTION) {
            dd("starting rotate");

            rotate_degrees = ngx_http_gm_get_str_value(r,
                    option->rotate_degrees_cv, &option->rotate_degrees);

            if (rotate_degrees == NULL) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                        "gm filter: rotate image, get rotate degrees failed");
                return  NGX_ERROR;
            }

            if (ngx_strchr(rotate_degrees,'>') != (char *) NULL) {
                if ((*image)->columns <= (*image)->rows)
                    continue;
                degrees_suffix_len = 1;
            }

            if (ngx_strchr(rotate_degrees,'<') != (char *) NULL) {
                if ((*image)->columns >= (*image)->rows)
                    continue;
                degrees_suffix_len = 1;
            }

            degrees = 0;
            degrees = ngx_atoi(rotate_degrees,
                               ngx_strlen(rotate_degrees) - degrees_suffix_len);

            if (degrees == 0) {
                continue;
            }

            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "rotate image degrees: \"%O\"", degrees);

            GetExceptionInfo(&exception);


            rotate_image=RotateImage(*image, degrees, &exception);
            if (rotate_image == (Image *) NULL) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                              "gm filter: rotate image failed, "
                              "degrees: \"%s\" severity: \"%O\" "
                              "reason: \"%s\", description: \"%s\"",
                              option->rotate_degrees, exception.severity,
                              exception.reason, exception.description);

                DestroyExceptionInfo(&exception);

                return NGX_ERROR;
            }

            DestroyImage(*image);
            *image = rotate_image;

            DestroyExceptionInfo(&exception);

        } else {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                              "gm filter: convert command, unkonwn option");
            return NGX_ERROR;
        }
    }

    return NGX_OK;
}
Пример #18
0
static void create_level(Image *image, char *type, int level,
			 unsigned long width, unsigned long height,
			 unsigned int columns, unsigned int rows)
{
	int i;
	unsigned int row = 0;
	unsigned int col = 0;
	unsigned int xoff = 0;
	unsigned int yoff = 0;
	char dname[NAME_MAX + 1];
	Image *rimage;
	ImageInfo *image_info;
	ExceptionInfo exception;
	RectangleInfo cropper;

	GetExceptionInfo(&exception);
	image_info = CloneImageInfo((ImageInfo *)NULL);
	rimage = ResizeImage(image, width, height, LanczosFilter, 1.0,
			&exception);
	memset(&cropper, 0, sizeof(cropper));

	snprintf(dname, NAME_MAX + 1, "%d", level);
	mkdir(dname, 0777);

	/* We create the tiles by columns */
	for (i = 0; i < columns * rows; i++) {
		Image *tile;

		if (i % rows == 0 && i != 0) {
			/* Start a new column */
			col++;
			row = 0;
			xoff = col * TILE_SZ;
			yoff = 0;
		}

		/*
		 * A lot of the complexity here is to cater for having
		 * overlap in the tiles.
		 */

		/* Are we the top left tile? */
		if (col == 0 && row == 0) {
			cropper.width = TILE_SZ + OVERLAP;
			cropper.height = TILE_SZ + OVERLAP;
		/* Are we the top right tile? */
		} else if (col == columns - 1 && row == 0) {
			cropper.width = TILE_SZ + OVERLAP;
			cropper.height = TILE_SZ + OVERLAP;
			cropper.x = xoff - OVERLAP;
			cropper.y = yoff;
		/* Are we the bottom left tile? */
		} else if (col == 0 && row == rows - 1) {
			cropper.width = TILE_SZ + OVERLAP;
			cropper.height = TILE_SZ + OVERLAP;
			cropper.y = yoff - OVERLAP;
		/* Are we the bottom right tile? */
		} else if (col == columns - 1 && row == rows - 1) {
			cropper.width = TILE_SZ + OVERLAP;
			cropper.height = TILE_SZ + OVERLAP;
			cropper.x = xoff - OVERLAP;
			cropper.y = yoff - OVERLAP;
		/* Are we on the top edge? */
		} else if (row == 0) {
			cropper.width = TILE_SZ + (OVERLAP * 2);
			cropper.height = TILE_SZ + OVERLAP;
			cropper.x = xoff - OVERLAP;
			cropper.y = yoff;
		/* Are we on the bottom edge? */
		} else if (row == rows - 1) {
			cropper.width = TILE_SZ + (OVERLAP * 2);
			cropper.height = TILE_SZ + OVERLAP;
			cropper.x = xoff - OVERLAP;
			cropper.y = yoff - OVERLAP;
		/* Are we on the left hand edge? */
		} else if (col == 0) {
			cropper.width = TILE_SZ + OVERLAP;
			cropper.height = TILE_SZ + (OVERLAP * 2);
			cropper.y = yoff - OVERLAP;
		/* Are we on the right hand edge? */
		} else if (col == columns - 1) {
			cropper.width = TILE_SZ + OVERLAP;
			cropper.height = TILE_SZ + (OVERLAP * 2);
			cropper.x = xoff - OVERLAP;
			cropper.y = yoff - OVERLAP;
		/* We are an internal tile */
		} else {
			cropper.width = TILE_SZ + (OVERLAP * 2);
			cropper.height = TILE_SZ + (OVERLAP * 2);
			cropper.x = xoff - OVERLAP;
			cropper.y = yoff - OVERLAP;
		}

		tile = CropImage(rimage, &cropper, &exception);
		snprintf(tile->filename, sizeof(tile->filename), "%d/%u_%u.%s",
			level, col, row, type);
		WriteImage(image_info, tile);
		DestroyImage(tile);

		/* Adjust the y (height) offset for the next row */
		yoff += TILE_SZ;
		row++;
	}

	DestroyImage(rimage);
	DestroyImageInfo(image_info);
	DestroyExceptionInfo(&exception);
}
Пример #19
0
HRESULT UIPdfTrimColumnedDlg::Draw(DK_IMAGE drawingImg)
{
	DebugPrintf(DLC_ZHY,"enter %s::%s,%s(%d)",GetClassName(), __FUNCTION__, __FILE__, __LINE__);
	if (!IsVisible())
		return S_OK;
	HRESULT hr(S_OK);
	CTpGraphics grf(drawingImg);
	DK_IMAGE imgSelf;
	DK_RECT rcSelf={m_iLeft, m_iTop, m_iLeft + m_iWidth, m_iTop + m_iHeight};
	RTN_HR_IF_FAILED(CropImage(drawingImg, rcSelf, &imgSelf));

	RTN_HR_IF_FAILED(DrawBackGround(imgSelf));

	//draw flag
	SPtr<ITpImage> spImageCursor = ImageManager::GetImage(IMAGE_PDF_LOCATE_CURSOR);
	int w = spImageCursor->GetWidth();
	int h = spImageCursor->GetHeight();

	if (m_bIsActionFinished) 
    {
		m_btnConfirmed.SetVisible(true);
		m_btnCancel.SetVisible(true);
		RTN_HR_IF_FAILED(m_btnConfirmed.Draw(imgSelf));
		RTN_HR_IF_FAILED(m_btnCancel.Draw(imgSelf));
	} 
    else 
    {
		m_btnConfirmed.SetVisible(false);
		m_btnCancel.SetVisible(false);
	}

	//draw lines
	if (m_iCurAction == PdfTrimAction) 
    {
		//Trim
		grf.DrawImage(spImageCursor.Get(), m_iLeftCuttingEdge - w/2, m_iTopCuttingEdge -h/2);
		grf.DrawImage(spImageCursor.Get(), m_iRightCuttingEdge - w/2, m_iBottomCuttingEdge - h/2);

		DebugPrintf(DLC_ZHY,"rect,left,top,right,bottom:%d,%d,%d,%d",m_iLeftCuttingEdge, m_iTopCuttingEdge, m_iRightCuttingEdge, m_iBottomCuttingEdge);
		grf.DrawLine(m_iLeftCuttingEdge, m_iTop, 2, m_iHeight, SOLID_STROKE);
		grf.DrawLine(m_iRightCuttingEdge, m_iTop, 2, m_iHeight, SOLID_STROKE);
		grf.DrawLine(m_iLeft, m_iTopCuttingEdge, m_iWidth, 2, SOLID_STROKE);
		grf.DrawLine(m_iLeft, m_iBottomCuttingEdge, m_iWidth, 2, SOLID_STROKE);
	}
    else 
    {
		grf.DrawLine(m_iColumnedX, m_iTop, 2, m_iHeight, SOLID_STROKE);
		grf.DrawImage(spImageCursor.Get(), m_iColumnedX - w/2, m_iColumnedY - h/2);

		if (m_iCurAction==PdfColumnedComicOrderLR || m_iCurAction==PdfColumnedComicOrderRL) 
        {
			//split to 2 pages
		} 
        else 
        {
			//split to 4 pages
			grf.DrawLine(m_iLeft, m_iColumnedY, m_iWidth, 2, SOLID_STROKE);
		}
	}
	if (m_btnTips.IsVisible())
		m_btnTips.SetVisible(false);

	DebugPrintf(DLC_ZHY,"leave %s::%s,%s(%d)",GetClassName(), __FUNCTION__, __FILE__, __LINE__);

	return hr;
}
Пример #20
0
int 
main(int argc, char **argv)
{
  int c;
  char* inputFile = 0;
  char* outputFile = 0;

  ExceptionInfo  exception;

  config.argv = argv;

  InitializeMagick(NULL);
  image.imageInfo=CloneImageInfo(0);
  GetExceptionInfo(&exception);
  
  while (1) {
    static struct option long_options[] = {
      {"verbose", no_argument, &config.verbose, 1},
      {"width",  required_argument, 0, 'w'},
      {"height",  required_argument, 0, 'h'},
      {"output",  required_argument, 0, 'o'},
      {"input",   required_argument, 0, 'i'},
      {"x",   required_argument, 0, 'x'},
      {"y",   required_argument, 0, 'y'},
      {"dx",   required_argument, 0, 'd'},
      {"dy",   required_argument, 0, 'f'},
      {"rows",   required_argument, 0, 'r'},
      {"cols",   required_argument, 0, 'c'},
      {0, 0, 0, 0}
    };
    
    int option_index = 0;

    
    c = getopt_long (argc, argv, "o:i:w:h:b:", long_options, &option_index);
    
    if (c == -1)
      break;
    
    switch (c) {
    case 0:
      break;
    case 'i':
      inputFile = optarg;
      break;	
    case 'o':
      outputFile = optarg;
      break;	
    case 'w':
      if (sscanf(optarg, "%d", &config.width) != 1) {
	abort_("invalid width");
      }
      break;	      
    case 'h':
      if (sscanf(optarg, "%d", &config.height) != 1) {
	abort_("invalid height");
      }
      break;	      
    case 'x':
      if (sscanf(optarg, "%d", &config.x) != 1) {
	abort_("invalid x");
      }
      break;	      
    case 'y':
      if (sscanf(optarg, "%d", &config.y) != 1) {
	abort_("invalid x");
      }
      break;	      
    case 'd':
      if (sscanf(optarg, "%d", &config.dx) != 1) {
	abort_("invalid dx");
      }
      break;	      
    case 'f':
      if (sscanf(optarg, "%d", &config.dy) != 1) {
	abort_("invalid dy");
      }
      break;	      
    case 'r':
      if (sscanf(optarg, "%d", &config.rows) != 1) {
	abort_("invalid rows");
      }
      break;	      
    case 'c':
      if (sscanf(optarg, "%d", &config.cols) != 1) {
	abort_("invalid cols");
      }
      break;
    case '?':
      usage();
      break;	
    default:
      usage();
      break;
    }
  }

  
  if (inputFile == 0 || outputFile == 0 || config.width == 0 || config.height == 0) {
    usage();
    abort();
  }

  if (config.dx == 0 ) {
    config.dx = config.width;
  }

  if (config.dy == 0 ) {
    config.dy = config.height;
  }

  if (config.verbose) {
    printf("x: %d, y: %d\n", config.x, config.y);
    printf("dx: %d, dy: %d\n", config.dx, config.dy);
    printf("width: %d, height: %d\n", config.width, config.height);
    printf("rows: %d, cols: %d\n", config.rows, config.cols);
  }

  (void) strcpy(image.imageInfo->filename, inputFile);
  image.image = ReadImage(image.imageInfo, &exception);
  if (image.image == (Image *) NULL) {
    CatchException(&exception);
    abort_("Failed to read image %s\n", inputFile);
  }


  for (int x = config.x, count = 0; x < config.x+(config.cols*config.dx); x += config.dx) {
    for (int y = config.y; y < config.y+(config.rows*config.dy); y += config.dy, count++) {
      RectangleInfo rect = {
	.x = x,
	.y =  y,
	.width = config.width,
	.height = config.height
      };
      
      if (config.verbose) {
	printf("row %d cols %d %ld %ld %ld %ld\n", (y-config.y)/config.dy, (x-config.x)/config.dx, rect.x, rect.y, rect.width, rect.height);
      }
      
      image.croppedImage = CropImage(image.image, &rect, &exception);

      if (config.rows > 1 || config.cols > 1) {
	sprintf(image.croppedImage->filename, "%s-%d.png", outputFile, count);
      } else {
	strcpy(image.croppedImage->filename, outputFile);
      }

      if (!WriteImage(image.imageInfo, image.croppedImage)) {
	CatchException(&image.croppedImage->exception);
	abort_("Failed to write image %d\n", outputFile);
      }

      if (image.croppedImage != (Image *)NULL) {
	DestroyImage(image.croppedImage);
      }      
    }
  }

  cleanup();

  return 0;
}
Пример #21
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   C r o p T o F i t I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method CropToFitImage crops the sheared image as determined by the bounding
%  box as defined by width and height and shearing angles.
%
%  The format of the CropToFitImage method is:
%
%      Image *CropToFitImage(Image **image,const double x_shear,
%        const double x_shear,const double width,const double height,
%        const unsigne int rotate,ExceptionInfo *exception)
%
%  A description of each parameter follows.
%
%    o image: The address of a structure of type Image.
%
%    o x_shear, y_shear, width, height: Defines a region of the image to crop.
%
%    o exception: Return any errors or warnings in this structure.
%
%
*/
static void CropToFitImage(Image **image,const double x_shear,
  const double y_shear,const double width,const double height,
  const unsigned int rotate,ExceptionInfo *exception)
{
  Image
    *crop_image;

  PointInfo
    extent[4],
    min,
    max;

  RectangleInfo
    geometry;

  register long
    i;

  /*
    Calculate the rotated image size.
  */
  extent[0].x=(-width/2.0);
  extent[0].y=(-height/2.0);
  extent[1].x=width/2.0;
  extent[1].y=(-height/2.0);
  extent[2].x=(-width/2.0);
  extent[2].y=height/2.0;
  extent[3].x=width/2.0;
  extent[3].y=height/2.0;
  for (i=0; i < 4; i++)
  {
    extent[i].x+=x_shear*extent[i].y;
    extent[i].y+=y_shear*extent[i].x;
    if (rotate)
      extent[i].x+=x_shear*extent[i].y;
    extent[i].x+=(double) (*image)->columns/2.0;
    extent[i].y+=(double) (*image)->rows/2.0;
  }
  min=extent[0];
  max=extent[0];
  for (i=1; i < 4; i++)
  {
    if (min.x > extent[i].x)
      min.x=extent[i].x;
    if (min.y > extent[i].y)
      min.y=extent[i].y;
    if (max.x < extent[i].x)
      max.x=extent[i].x;
    if (max.y < extent[i].y)
      max.y=extent[i].y;
  }
  geometry.width=(unsigned long) floor(max.x-min.x+0.5);
  geometry.height=(unsigned long) floor(max.y-min.y+0.5);
  geometry.x=(long) ceil(min.x-0.5);
  geometry.y=(long) ceil(min.y-0.5);
  crop_image=CropImage(*image,&geometry,exception);
  if (crop_image != (Image *) NULL)
    {
      crop_image->page=(*image)->page;
      DestroyImage(*image);
      *image=crop_image;
    }
}
Пример #22
0
HGLOBAL ResizeImage(const BITMAPINFO *pbmiSrc,const void *pSrcData,
									const RECT *pSrcRect,int Width,int Height)
{
	HGLOBAL hGlobal;
	BITMAPINFOHEADER *pbmihDst;
	void *pDstData;
	int *pnSrcPos;
	int SrcLeft,SrcTop,SrcWidth,SrcHeight;
	int SrcPlanes,SrcXCenter,SrcYCenter,DstXCenter,DstYCenter;
	int x,y,x1,y1,dx1,dy1,dx2,dy2,YOffset;
	int b,g,r;
	int SrcRowBytes,DstPadBytes;
	const BYTE *p,*p1;
	BYTE *q;

	if (pbmiSrc->bmiHeader.biBitCount!=24 && pbmiSrc->bmiHeader.biBitCount!=32)
		return NULL;
	hGlobal=GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
					sizeof(BITMAPINFOHEADER)+DIB_ROW_BYTES(Width,24)*Height);
	if (hGlobal==NULL)
		return NULL;
	pbmihDst=(BITMAPINFOHEADER*)GlobalLock(hGlobal);
	pbmihDst->biSize=sizeof(BITMAPINFOHEADER);
	pbmihDst->biWidth=Width;
	pbmihDst->biHeight=Height;
	pbmihDst->biPlanes=1;
	pbmihDst->biBitCount=24;
	pbmihDst->biCompression=BI_RGB;
	pbmihDst->biSizeImage=0;
	pbmihDst->biXPelsPerMeter=0;
	pbmihDst->biYPelsPerMeter=0;
	pbmihDst->biClrUsed=0;
	pbmihDst->biClrImportant=0;
	pDstData=pbmihDst+1;
	if (pSrcRect!=NULL) {
		SrcLeft=pSrcRect->left;
		SrcTop=pSrcRect->top;
		SrcWidth=pSrcRect->right-pSrcRect->left;
		SrcHeight=pSrcRect->bottom-pSrcRect->top;
	} else {
		SrcLeft=SrcTop=0;
		SrcWidth=pbmiSrc->bmiHeader.biWidth;
		SrcHeight=abs(pbmiSrc->bmiHeader.biHeight);
	}
	if (SrcWidth==Width && SrcHeight==Height) {
		CropImage(pbmiSrc,pSrcData,SrcLeft,SrcTop,Width,Height,pDstData);
		GlobalUnlock(hGlobal);
		return hGlobal;
	}
	SrcPlanes=pbmiSrc->bmiHeader.biBitCount/8;
	pnSrcPos=new int[Width];
	SrcXCenter=((SrcWidth-1)<<8)/2;
	SrcYCenter=((SrcHeight-1)<<8)/2;
	DstXCenter=((Width-1)<<8)/2;
	DstYCenter=((Height-1)<<8)/2;
	for (x=0;x<Width;x++) {
		pnSrcPos[x]=((x<<8)-DstXCenter)*SrcWidth/Width+SrcXCenter;
		if (pnSrcPos[x]<0)
			pnSrcPos[x]=0;
		else if (pnSrcPos[x]>(SrcWidth-1)<<8)
			pnSrcPos[x]=(SrcWidth-1)<<8;
	}
	SrcRowBytes=DIB_ROW_BYTES(pbmiSrc->bmiHeader.biWidth,
												pbmiSrc->bmiHeader.biBitCount);
	DstPadBytes=DIB_ROW_BYTES(Width,24)-Width*3;
	if (SrcTop>0)
		pSrcData=static_cast<const BYTE*>(pSrcData)+
			(pbmiSrc->bmiHeader.biHeight>0?(pbmiSrc->bmiHeader.biHeight-(SrcHeight+SrcTop)):SrcTop)*SrcRowBytes;
	q=(BYTE*)pDstData;
	for (y=0;y<Height;y++) {
		y1=((y<<8)-DstYCenter)*SrcHeight/Height+SrcYCenter;
		if (y1<0)
			y1=0;
		else if (y1>(SrcHeight-1)<<8)
			y1=(SrcHeight-1)<<8;
		dy2=y1&0xFF;
		dy1=0x100-dy2;
		YOffset=dy2>0?SrcRowBytes:0;
		for (x=0;x<Width;x++) {
			x1=pnSrcPos[x];
			dx2=x1&0xFF;
			dx1=0x100-dx2;
			p=static_cast<const BYTE*>(pSrcData)+(y1>>8)*SrcRowBytes+
												((x1>>8)+SrcLeft)*SrcPlanes;
			p1=p+((dx2+0xFF)>>8)*SrcPlanes;
			b=(p[0]*dx1+p1[0]*dx2)*dy1;
			g=(p[1]*dx1+p1[1]*dx2)*dy1;
			r=(p[2]*dx1+p1[2]*dx2)*dy1;
			p+=YOffset;
			p1+=YOffset;
			b+=(p[0]*dx1+p1[0]*dx2)*dy2;
			g+=(p[1]*dx1+p1[1]*dx2)*dy2;
			r+=(p[2]*dx1+p1[2]*dx2)*dy2;
			*q++=b>>16;
			*q++=g>>16;
			*q++=r>>16;
		}
		q+=DstPadBytes;
	}
	delete [] pnSrcPos;
	GlobalUnlock(hGlobal);
	return hGlobal;
}