bool
MediaEngineGonkVideoSource::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight) {
  {
    ReentrantMonitorAutoEnter sync(mCallbackMonitor);
    if (mState == kStopped) {
      return false;
    }
  }

  MonitorAutoLock enter(mMonitor);
  // Bug XXX we'd prefer to avoid converting if mRotation == 0, but that causes problems in UpdateImage()
  RotateImage(aImage, aWidth, aHeight);
  if (mRotation != 0 && mRotation != 180) {
    uint32_t temp = aWidth;
    aWidth = aHeight;
    aHeight = temp;
  }
  if (mWidth != static_cast<int>(aWidth) || mHeight != static_cast<int>(aHeight)) {
    mWidth = aWidth;
    mHeight = aHeight;
    LOG(("Video FrameSizeChange: %ux%u", mWidth, mHeight));
  }

  return true; // return true because we're accepting the frame
}
Ejemplo n.º 2
0
/// get 4 lines from 4 quater correspondingly, a line
/// can be empry if there is no line in that quater
///
QImage Rotater::readLines( const QImage image, vector<Form> *lines)
{
    QImage destImage = QImage( image);
    QImage blackImage = QImage( image);
    blackImage.fill( 0);

    // edges detection
    edge_detector ed = edge_detector();
//    destImage = ed.smoothImage(destImage);
    destImage = ed.detectEdgeImage(destImage, 0);
    destImage = ed.nmsImage(destImage);
    destImage = ed.double_thresholding(destImage);
    destImage = ed.blob_extract(destImage);
    destImage = RotateImage(destImage, blackImage);
    destImage = HideRollOutCorners(destImage);

    // collect master line (1 or 0) from each quater
    for (int i=1; i<=4; i++)
    {
        Form line;
        get_master_line(destImage, i, &line);
        lines->push_back(line);

        // commented off to avoid interfering the result
//        if (line.vote == 0) continue;                                       // TEST
//        destImage = m_line_detector->display_voting_map(destImage, false);  // TEST
//        destImage = m_line_detector->display_lines(destImage, *lines, 3);   // TEST
    }
    m_line_detector->print(*lines, LineFacts, -1);

    return destImage;
}
void RegionsToSIFTDescriptors( PStack regions, PStack descriptors, int pb, int ob, int psize ) {
	
	if ( regions == NULL || descriptors == NULL ) return;
	
	if ( psize % 2 == 0 ) psize++;
	Image patch = CreateImage(psize*sqrt(2),psize*sqrt(2));
	Image rpatch = CreateImage(psize,psize);
	FStack orientations = NewFStack(15);
	
	int k;
	
	for (k=0;k<regions->stacksize;k++) {
		Region region = regions->items[k];
		RegionToPatch(region,region->image,patch,6.0);
		DeterminePatchOrientations(patch,orientations);
		while ( !FStackEmpty(orientations) ) {
			float orientation = PopFStack(orientations);
			RotateImage(patch,rpatch,orientation);
			float * newDescriptor = PCADescriptorFromPatch(rpatch);
			PushPStack(descriptors,NewDescriptor(region,36,3,newDescriptor));
		}
	}
	
	FreeFStack(orientations);
	FreeImage(patch); FreeImage(rpatch);

}
Ejemplo n.º 4
0
void MainWindow::RotateImage()
{
    double orien = ui->orientationSpinBox->value();

    RotateImage(&outImage, orien);

    DrawDisplayImage();
}
Ejemplo n.º 5
0
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(ui->openButton, SIGNAL(clicked()), this, SLOT(OpenImage()));
    connect(ui->saveButton, SIGNAL(clicked()), this, SLOT(SaveImage()));
    connect(ui->saveDisplayButton, SIGNAL(clicked()), this, SLOT(SaveDisplayImage()));
    connect(ui->resetButton, SIGNAL(clicked()), this, SLOT(ResetImage()));
    connect(ui->toggleButton, SIGNAL(pressed()), this, SLOT(ToggleImage()));
    connect(ui->toggleButton, SIGNAL(released()), this, SLOT(ToggleImage()));

    connect(ui->bwButton, SIGNAL(clicked()), this, SLOT(BlackWhiteImage()));
    connect(ui->noiseButton, SIGNAL(clicked()), this, SLOT(AddNoise()));
    connect(ui->meanButton, SIGNAL(clicked()), this, SLOT(MeanBlurImage()));
    connect(ui->medianButton, SIGNAL(clicked()), this, SLOT(MedianImage()));
    connect(ui->gaussianBlurButton, SIGNAL(clicked()), this, SLOT(GaussianBlurImage()));
    connect(ui->firstDerivButton, SIGNAL(clicked()), this, SLOT(FirstDerivImage()));
    connect(ui->secondDerivButton, SIGNAL(clicked()), this, SLOT(SecondDerivImage()));
    connect(ui->sharpenButton, SIGNAL(clicked()), this, SLOT(SharpenImage()));
    connect(ui->sobelButton, SIGNAL(clicked()), this, SLOT(SobelImage()));
    connect(ui->bilateralButton, SIGNAL(clicked()), this, SLOT(BilateralImage()));
    connect(ui->halfButton, SIGNAL(clicked()), this, SLOT(HalfImage()));
    connect(ui->rotateButton, SIGNAL(clicked()), this, SLOT(RotateImage()));
    connect(ui->peaksButton, SIGNAL(clicked()), this, SLOT(FindPeaksImage()));
    connect(ui->houghButton, SIGNAL(clicked()), this, SLOT(HoughImage()));
    connect(ui->crazyButton, SIGNAL(clicked()), this, SLOT(CrazyImage()));
    connect(ui->randomButton, SIGNAL(clicked()), this, SLOT(RandomSeedImage()));
    connect(ui->pixelButton, SIGNAL(clicked()), this, SLOT(PixelSeedImage()));
    connect(ui->histogramButton, SIGNAL(clicked()), this, SLOT(HistogramSeedImage()));

    connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(OpenImage()));
    connect(ui->zoomSlider, SIGNAL(valueChanged(int)), this, SLOT(Zoom(int)));
    connect(ui->brightnessSlider, SIGNAL(valueChanged(int)), this, SLOT(Brightness(int)));
    connect(ui->verticalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(Scroll(int)));
    connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(Scroll(int)));

    ui->meanBox->setValue(2);
    ui->medianBox->setValue(2);
    ui->blurSpinBox->setValue(2.0);
    ui->firstDerivSpinBox->setValue(2.0);
    ui->secondDerivSpinBox->setValue(2.0);
    ui->sharpenSigmaSpinBox->setValue(2.0);
    ui->sharpenMagSpinBox->setValue(1.0);
    ui->bilateralSigmaSSpinBox->setValue(2.0);
    ui->bilateralSigmaISpinBox->setValue(20.0);
    ui->noiseSpinBox->setValue(10.0);
    ui->orientationSpinBox->setValue(10.0);
    ui->peakThresholdSpinBox->setValue(10.0);
    ui->colorNoiseCheckBox->setChecked(true);
    ui->zoomSlider->setValue(0);
    ui->brightnessSlider->setValue(0);
    ui->clusterBox->setValue(4);

    displayImage = QImage(ui->ImgDisplay->width(), ui->ImgDisplay->height(), QImage::Format_RGB32);
}
Ejemplo n.º 6
0
void CIMDisplayView::OnRotate() 
{
    CRotateDialog   dlg;
    dlg.Angle( 180 );	// good default as any...

    if ( dlg.DoModal() == IDOK ) {
	RotateImage( dlg.Angle() );
    }
}
Ejemplo n.º 7
0
Image       *rotate_image(Image *img, int degrees){
    Image           *retated_img = NULL;
    ExceptionInfo	exception;
    GetExceptionInfo(&exception);
    
    retated_img = RotateImage(img, degrees, &exception);
    DestroyImage(img);
    SyncImagePixels(retated_img);
    return (retated_img);
}
void CImage::DecodeComplete(CFbsBitmap* aBitmap, CFbsBitmap* aMask)
{
   delete iBitmap;
   delete iMask;
   iBitmap = aBitmap;
   iMask = aMask;
   
   if(iRotateStatus == ERotationPending)
   {
      RotateImage();
      iRotateStatus = ERotationNone;
   }
   iIsReady = ETrue;
   DrawNow();
}
Ejemplo n.º 9
0
bool CapsuleProc::RotateIMG(	size_t	blobIndex,
								FBLOB	profileBlob,
								IMG		proImg,
								IMG		&proSubIMG,
								size_t	&posIndex)
{
	long profileCount = 0;
	FBlobGetNumBlobs	(profileBlob, profileCount);
	if ( blobIndex >= static_cast<size_t>(profileCount) )
	{
		posIndex = -1;
		return false;
	}

	//Get Range
	long	x0 = 0,		y0 = 0,		width = 0,	height = 0;	
	FBlobGetBoundingBox	(profileBlob, blobIndex, x0, y0, width, height);
	posIndex = CheckPosition(x0+width/2, y0+height/2);

	IMG		proIMGMap	= NULL;
	CreateImageMap	(proImg,  x0, y0, x0+width, y0+height, width, height,	proIMGMap);

	double	rabi = 0.0, rabi1 = 0.0, rabi2 = 0.0, momentAngle = 0.0;
	FBlobGetMoments	(profileBlob, blobIndex, rabi, rabi1, rabi2, momentAngle);

	static const double ADIVPI		= 180.0 /(4.0*atan(1.0));	//ppi	= 180/PI
	static const double ANGLE90		= 90;					//ppiH	= 180/PI*PI/2

	double angle = 0.0;
	if(momentAngle>=0)
	{	angle =  (ANGLE90 - ADIVPI * momentAngle);	}
	else 
	{	angle = -(ANGLE90 + ADIVPI * momentAngle);	}
	
	RotateImage(	proIMGMap,	angle,	IP_Linear,	proSubIMG);	

	TCoordinateMap cm;
	InitCoordinateMap(cm);
	SetImageCoordinates (proSubIMG, cm); 	

	ShrinkVertical	(proSubIMG, m_segmentParam.shrinkY);	
	ShrinkHorizontal(proSubIMG, m_segmentParam.shrinkX);
	
	ReleaseImage	(proIMGMap);
	return true;
}
Ejemplo n.º 10
0
void TextureAtlas::addImage(ImageHandle newImageHandle, Rectangle newRect)
{
    Image* newImage = newImageHandle.Resolve();

    bool wasRotated = newImage->getWidth() == newRect.height &&
                      newImage->getHeight() == newRect.width;

    Image* atlasImage = atlasImageHandle.Resolve();

    assert(newImage->getPixelFormat() == atlasImage->getPixelFormat());

    if (wasRotated)
        RotateImage(newImage,atlasImage,Vector2i(newRect.x,newRect.y));
    else
        atlasImage->setBuffer(newImage,Vector2i(newRect.x,newRect.y));

    SubTexture subTexture;
    subTexture.atlas = this;

    float bottom = (float)(newRect.y+newRect.height)/atlasSize;
    float top = (float)newRect.y/atlasSize;
    float right = (float)(newRect.x+newRect.width)/atlasSize;
    float left = (float)newRect.x/atlasSize;

    if(!wasRotated)
    {
        subTexture.leftTopUV = Vector2(left,top);
        subTexture.rightTopUV = Vector2(right,top);
        subTexture.rightBottomUV = Vector2(right,bottom);
        subTexture.leftBottomUV = Vector2(left,bottom);
    } 
    else 
    {
        subTexture.rightTopUV = Vector2(left,top);
        subTexture.rightBottomUV = Vector2(right,top);
        subTexture.leftBottomUV = Vector2(right,bottom);
        subTexture.leftTopUV = Vector2(left,bottom);
    }

    imageSubTextures[newImageHandle] = subTexture;
}
Ejemplo n.º 11
0
// 传进来一个contour,然后计算它的最小包围矩形minRect,再把原图以包围矩形中心为旋转中心旋转minRect.angle°,得到调正的图像。
// http://blog.csdn.net/include1224/article/details/4384855
CvBox2D RegionRotate(IplImage *src, IplImage *dst, CvSeq *contour) {
	//dst 是通过cvClone()src得到的
	CvMat *mat_contour = cvCreateMat(1, contour->total, CV_32FC2); 	//双通道
	CvPoint2D32f *ptr_mat = (CvPoint2D32f*) (mat_contour->data.ptr);
	for (int i = 0; i != contour->total; ++i) {
		CvPoint *ptr_seq = (CvPoint*) (cvGetSeqElem(contour, i));
		*ptr_mat = cvPointTo32f(*ptr_seq); 			//显示把CvPoint转换成CvPoint2D32F
		ptr_mat++;
	} //把轮廓变成矩阵
	CvBox2D minRect = cvMinAreaRect2(mat_contour); 			//得到最小包围矩形
	//CvMat *rot = cvCreateMat(2,3,CV_32FC1);
	//cv2DRotationMatrix(cvPoint2D32f(src->width*0.5f,src->height*0.5f),minRect.angle,0.6,rot);//计算得到旋转矩阵----这里计算得到的矩阵不能使图像变换到想要的旋转结果
	float factor = 1.0; //缩放
	float angle = -minRect.angle;
	float w = 0, h = 0;
	w = minRect.center.x;
	h = minRect.center.y;
	RotateImage(src, dst, cvPoint(w, h), angle, factor);
	//cvEllipseBox(dst,minRect,cvScalar(0,0,255));
	cvReleaseMat(&mat_contour);
	return minRect; //返回最佳包围盒
}
Ejemplo n.º 12
0
static void GenSmallImage( int img_count, CImage &back, const RectF &render_rect, int sel, CImage &img_alpha )
{
#define RAND_ALPHA ( ( 130 + random( 50 ) ) / 255.0f )
#define ROT_ANGLE ( random( 20 ) + 160 )
    if( img_count < 1 )
    {
        return ;
    }

    CFileListManager &file_manager = GetInst( CFileListManager );

    const Range &alpha_r = GetInst( CConfiger ).GetSystem().AnswerAlphaRange;
    float fAnswerAlpha = ( random( alpha_r.second - alpha_r.first ) + alpha_r.first ) / 255.0f;
    CImage img_first;
    CreateImgFromBuffer( file_manager.GetRandSmall(), img_first, true );
    float fFirstRot = ROT_ANGLE;
    float fFirstAlpha = RAND_ALPHA;
    PointF pos = RotateImage( img_first, img_alpha, img_count == 1 ? ( random( 60 ) - 30.0f ) : fFirstRot );
    PointF render_pos = GetRandPosInULRect( img_first.GetWidth(), img_first.GetHeight(), render_rect );
    RectF img_rect( render_pos.X + 20, render_pos.Y + 20, img_first.GetWidth() - 40, img_first.GetHeight() - 40 );
    back.AlphaBlend( &img_first, render_pos.X, render_pos.Y,
                     img_count == 1 ? fAnswerAlpha : fFirstAlpha );

    CImage *img_cover = NULL;
    PointF rot_pos = GetRotPos( img_alpha, pos );
    float fRotQuo = 20.0f;
    float fAlphaQuo = -0.08f;
    for( int i = 1; i < img_count; ++ i, fRotQuo += fRotQuo, fAlphaQuo += fAlphaQuo )
    {
        img_cover = MP_NEW CImage();
        CreateImgFromBuffer( file_manager.GetRandSmall(), *img_cover, true );
        img_cover->RotateEx( fFirstRot + fRotQuo, rot_pos.X, rot_pos.Y );
        img_cover->SetAlphaMap( &img_alpha, pos.X, pos.Y );
        back.AlphaBlend( img_cover, render_pos.X, render_pos.Y, fFirstAlpha + fAlphaQuo );
        MP_DELETE(img_cover);
    }

    BlendSelSign( back, img_rect, sel );
}
Ejemplo n.º 13
0
QImage Rotater::RotateWithCornerFilling(const QImage image)
{
    QImage destImage = QImage( image);
    QImage origImage = QImage( image);

    vector<Form> lines;

    readLines(destImage, &lines);
//    m_line_detector->print(lines, LineFacts, -1);

    for (int quater=1; quater<=4; quater++)
    {
        get_shift_values(quater, lines.at(quater-1));
//        if (quater != 1) continue;
//        destImage = markOnImage( destImage, m_dx[0], m_dy[0], 1); // TEST
//        destImage = markOnImage( destImage, m_dx[5], m_dy[5], 0); // TEST
    }
    destImage = shiftImage( destImage);

    destImage = RotateImage( destImage, origImage);

    return destImage;
}
Ejemplo n.º 14
0
VImage VRotateImage (VImage src, VImage dest, VBand band, double angle)
{
#define Tolerance 0.01

  double angle_remained;
  VImage tmp1 = NULL, tmp2;

  /* Normalize angle to the range [-Pi, +Pi]: */
  angle = fmod (angle, 2.0 * M_PI);
  if (angle > M_PI)
    angle -= 2.0 * M_PI;

  /* 
   * Two stage rotation:
   * 1. Use flipping to rotate the image by a multiple of 90 degrees.
   * 2. Use RotateImage() to rotate the remaining angle.
   */
  if (angle >= -0.25 * M_PI && angle <= 0.25 * M_PI) {

    /* Do nothing: */
    angle_remained = angle;
    tmp2 = src;

  } else if (angle >= 0.25 * M_PI && angle <= 0.75 * M_PI) {

    /* Rotate by 90 degrees: */
    tmp1 = VTransposeImage (src, NULL, band);
    tmp2 = VFlipImage (tmp1, NULL, VAllBands, TRUE);
    angle_remained = angle - 0.5 * M_PI;

  } else if (angle >= 0.75 * M_PI || angle <= -0.75 * M_PI) {

    /* Rotate by 180 degrees: */
    tmp1 = VFlipImage (src, NULL, band, TRUE);
    tmp2 = VFlipImage (tmp1, NULL, VAllBands, FALSE);
    angle_remained = angle > 0.0 ? angle - M_PI : angle + M_PI;

  } else {

    /* Rotate by -90 degress: */
    tmp1 = VTransposeImage (src, NULL, band);
    tmp2 = VFlipImage (tmp1, NULL, VAllBands, FALSE);
    angle_remained = angle + 0.5 * M_PI;
  }

  if (VMax (angle_remained, -angle_remained) > Tolerance) {

    /* Go on to stage 2: */
    dest = RotateImage (tmp2, dest, tmp2 == src ? band : VAllBands, 
			angle_remained);

  } else {

    /* Stage 1 only is good enough: */
    dest = VCopyImage (tmp2, dest, tmp2 == src ? band : VAllBands);
  }
    
  /* Clean up: */
  if (tmp2 != src) {
    VDestroyImage (tmp1);
    VDestroyImage (tmp2);
  }
    
  return dest;
    
#undef Tolerance
}
Ejemplo n.º 15
0
void CIMDisplayView::OnRotateLeft() 
{
    RotateImage( -90 );
}
Ejemplo n.º 16
0
void CIMDisplayView::OnRotateRight() 
{
    RotateImage( 90 );
}
Ejemplo n.º 17
0
int MatchTemplate(const IplImage* pTemplate,
				  const IplImage* pSource,
				  double dAngle,
				  double dScore,
				  ShiftValue& iResult)
{
	// check the input params
	if (pTemplate == NULL || pSource == NULL)
	{
		printf("MatchTemplate input params is NULL!\n");
		return -1;
	}
	
	const CvSize iTemplateSize = cvGetSize(pTemplate);
	const CvSize iSrcSize = cvGetSize(pSource);
	if (iTemplateSize.height > iSrcSize.height
		|| iTemplateSize.width > iSrcSize.width)
	{
		printf("MatchTemplate Template size is larger than Source Image!\n");
		return -1;
	}

	if (dAngle < 0 || dAngle > 180)
	{
		printf("MatchTemplate input angle is out of range!\n");
		return -1;
	}
	// check the input params ends
	
	// pyrdown the source image
	// pyrdown times
	// get nPyrdownCount self-adaptively
	int nPyrdownCount = GetPyrdownTime(iTemplateSize, iSrcSize, 20);
	printf("PyrDown count is %d\n", nPyrdownCount);
	// pyrdowned source image
	IplImage* pPyrDownedSource = GetPyrDownImage(pSource, nPyrdownCount);
	// pyrdowned template image
	IplImage* pPyrDownedTemplate = GetPyrDownImage(pTemplate, nPyrdownCount);
	// pyrdown the source image ends
	
	// roughly match template
	double dFirstStep = 0.5;
	MatchWithAngle(pPyrDownedTemplate,
				   pPyrDownedSource,
				   dAngle,
				   dFirstStep,
				   iResult);
	// roughly match template ends
	
	// convert to init scale 
	// rotate source image with iResult.dA
	IplImage* pRotatedImage = RotateImage(pSource, iResult.dAngle);
	
	// set image ROI
	iResult.dX *= pow(2, nPyrdownCount);
	iResult.dY *= pow(2, nPyrdownCount);
	// 
	ShiftValue iRoughlyResult = iResult;
	
	printf("roughly matched result:\n");
	printf("X: %f\nY: %f\nAngle: %f\n",
		   iRoughlyResult.dX,
		   iRoughlyResult.dY,
		   iRoughlyResult.dAngle);
	
	// The top-left point of the ROI
	CvPoint iTopLeftPoint;
	double dExpand = 0.2;
	
	iResult.dX += iSrcSize.width / 2;
	iResult.dY += iSrcSize.height / 2;
	SetImageROIWithCenterPoint(pRotatedImage,
							   iTemplateSize,
							   cvPoint(iResult.dX, iResult.dY),
							   dExpand,
							   iTopLeftPoint);
	// convert to init scale ends
	
	IplImage* pCanniedTemplate = cvCloneImage(pTemplate);
	IplImage* pCanniedSource = cvCloneImage(pRotatedImage);
	ExpandEdge(pTemplate, pCanniedTemplate, 2);
	ExpandEdge(pRotatedImage, pCanniedSource, 2);
	
	// precisly match template
	MatchWithAngle(pCanniedTemplate,
				   pCanniedSource,
				   dFirstStep * 1.5,
				   dFirstStep * 0.1,
				   iResult);
	ShiftValue iTmpResult = iResult;
	
	printf("precisly matched result:\n");
	printf("X: %f\nY: %f\nAngle: %f\n",
		   iTmpResult.dX,
		   iTmpResult.dY,
		   iTmpResult.dAngle);	
	
	// add roughly match result and precisly match result to final result
	AddShiftParams(iRoughlyResult, iTmpResult, iResult);
	
	printf("final matched result:\n");
	printf("X: %f\nY: %f\nAngle: %f\n",
		   iResult.dX,
		   iResult.dY,
		   iResult.dAngle);	
	
	iResult.dX += iSrcSize.width / 2;
	iResult.dY += iSrcSize.height / 2;
	
	/*
	iTmpResult.dAngle += iRoughlyResult.dAngle;
	TranferCoordinate(iSrcSize.width / 2,
					  iSrcSize.height / 2,
					  iTmpResult,
					  iResult);
	*/
	// precisly match template ends
	
	cvReleaseImage(&pRotatedImage);
	cvReleaseImage(&pPyrDownedSource);
	cvReleaseImage(&pPyrDownedTemplate);
	cvReleaseImage(&pCanniedSource);
	cvReleaseImage(&pCanniedTemplate);
	return 1;
}
Ejemplo n.º 18
0
void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
{
    SCH_SCREEN* screen = GetScreen();
    SCH_ITEM*   item = screen->GetCurItem();

    INSTALL_UNBUFFERED_DC( dc, m_canvas );

    // Allows block rotate operation on hot key.
    if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK )
    {
        screen->m_BlockLocate.SetCommand( BLOCK_ROTATE );
        HandleBlockEnd( &dc );
        return;
    }

    if( item == NULL )
    {
        // If we didn't get here by a hot key, then something has gone wrong.
        if( aEvent.GetInt() == 0 )
            return;

        EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();

        wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );

        item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::RotatableItems,
                                  aEvent.GetInt() );

        // Exit if no item found at the current location or the item is already being edited.
        if( (item == NULL) || (item->GetFlags() != 0) )
            return;
    }

    switch( item->Type() )
    {
    case SCH_COMPONENT_T:
        if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE )
            OrientComponent( CMP_ROTATE_CLOCKWISE );
        else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE )
            OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE );
        else
            wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) );

        break;

    case SCH_TEXT_T:
    case SCH_LABEL_T:
    case SCH_GLOBAL_LABEL_T:
    case SCH_HIERARCHICAL_LABEL_T:
        m_canvas->MoveCursorToCrossHair();
        ChangeTextOrient( (SCH_TEXT*) item, &dc );
        break;

    case SCH_FIELD_T:
        m_canvas->MoveCursorToCrossHair();
        RotateField( (SCH_FIELD*) item, &dc );
        break;

    case SCH_BITMAP_T:
        RotateImage( (SCH_BITMAP*) item );
        break;

    case SCH_SHEET_T:           /// @todo allow sheet rotate on hotkey
    default:
        wxFAIL_MSG( wxString::Format( wxT( "Cannot rotate schematic item type %s." ),
                                      GetChars( item->GetClass() ) ) );
    }

    if( item->GetFlags() == 0 )
        screen->SetCurItem( NULL );
}
Ejemplo n.º 19
0
/*
 * ImgEdFrameProc - handle messages for the image editor application
 */
WPI_MRESULT CALLBACK ImgEdFrameProc( HWND hwnd, WPI_MSG msg,
                                 WPI_PARAM1 wparam, WPI_PARAM2 lparam )
{
    static BOOL         window_destroyed = FALSE;
    static HMENU        hmenu;
    ctl_id              cmdid;
    img_node            *node;
    WPI_RECT            rcmain;
#ifndef __OS2_PM__
    about_info          ai;
#endif
    WPI_RECTDIM         left, top;

    if( !window_destroyed ) {
        enableMainItems( hmenu );
    }

    switch( msg ) {
    case UM_EXIT:
        _wpi_sendmessage( hwnd, WM_COMMAND, IMGED_CLOSEALL, 0L );
        /* fall through */

    case UM_EXIT_NO_SAVE:
        if( _wpi_getfirstchild( _wpi_getclient( ClientWindow ) ) != NULL ) {
            break;
        }
#ifndef __OS2_PM__
        _wpi_destroywindow( _wpi_getframe( hwnd ) );
#else
        _wpi_sendmessage( hwnd, WM_CLOSE, 0, 0 );
#endif

        break;

    case UM_SAVE_ALL:
        SaveAllImages();
        break;

    case WM_CREATE:
        hmenu = _wpi_getmenu( _wpi_getframe( hwnd ) );
#ifndef __OS2_PM__
        createClientWindow( hwnd );
#endif
        if( !InitStatusLine( hwnd ) ) {
            return( -1 );
        }

        InitFunctionBar( hwnd );
        InitIconInfo();
        InitializeCursors();

        /*
         * Set values from profile information ...
         */
        if( ImgedConfigInfo.brush_size <= 5 && ImgedConfigInfo.brush_size >= 2 ) {
            checkBrushItem( hmenu, IMGED_2x2 - 2 + ImgedConfigInfo.brush_size );
        }
        if( ImgedConfigInfo.grid_on ) {
            CheckGridItem( hmenu );
        }
        if( ImgedConfigInfo.square_grid ) {
            CheckSquareGrid( hmenu );
        }
        if( ImgedConfigInfo.show_state & SET_SHOW_VIEW ) {
            CheckViewItem( hmenu );
        }

        _wpi_enablemenuitem( hmenu, IMGED_CRESET, FALSE, FALSE );
        _wpi_enablemenuitem( hmenu, IMGED_RCOLOR, FALSE, FALSE );
#ifndef __OS2_PM__
        // not necessary for PM
        InitMenus( hmenu );
#endif
        SetHintText( IEAppTitle );
        return( 0 );
#ifdef __NT__
    case WM_DROPFILES:
        OpenImage( (HANDLE)wparam );
        break;
#endif
    case WM_MOVE:
        _wpi_getwindowrect( hwnd, &rcmain );
        if( !ImgedConfigInfo.ismaximized ) {
            ImgedConfigInfo.last_xpos = ImgedConfigInfo.x_pos;
            ImgedConfigInfo.last_ypos = ImgedConfigInfo.y_pos;
            _wpi_getrectvalues( rcmain, &left, &top, NULL, NULL );
            ImgedConfigInfo.x_pos = (short)left;
            ImgedConfigInfo.y_pos = (short)top;
        }
        return( 0 );

    case WM_SIZE:
        ResizeFunctionBar( lparam );
        ResizeStatusBar( lparam );
#ifndef __OS2_PM__
        if( ClientWindow != NULL ) {
            setClientSize( hwnd );
        }
#else
        resizeClientArea( lparam );
#endif

        if( !_imgwpi_issizeminimized( wparam ) && !_imgwpi_issizemaximized( wparam ) ) {
            _wpi_getwindowrect( hwnd, &rcmain );
            ImgedConfigInfo.width = (short)_wpi_getwidthrect( rcmain );
            ImgedConfigInfo.height = (short)_wpi_getheightrect( rcmain );
            ImgedConfigInfo.ismaximized = FALSE;
        } else {
            ImgedConfigInfo.x_pos = ImgedConfigInfo.last_xpos;
            ImgedConfigInfo.y_pos = ImgedConfigInfo.last_ypos;
            ImgedConfigInfo.ismaximized = _imgwpi_issizemaximized( wparam );
        }
        return( FALSE );

    case WM_MENUSELECT:
#ifndef __OS2_PM__
        if( GET_WM_MENUSELECT_FLAGS( wparam, lparam ) & MF_SEPARATOR ) {
            break;
        }
        if( GET_WM_MENUSELECT_FLAGS( wparam, lparam ) & MF_SYSMENU ) {
            PrintHintTextByID( WIE_SYSMENUOPERATIONS, NULL );
            break;
        }
#endif
        ShowHintText( LOWORD( wparam ) );
        break;

    case WM_COMMAND:
        cmdid = LOWORD( wparam );
        if( !IEIsMenuIDValid( hmenu, cmdid ) ) {
            break;
        }
        switch( cmdid ) {
        case IMGED_NEW:
            if( !ImgedIsDDE ) {
                if( !NewImage( UNDEF_IMG, NULL ) ) {
                    PrintHintTextByID( WIE_NEIMAGENOTCREATED, NULL );
                }
            }
            break;

        case IMGED_CLOSE:
            node = GetCurrentNode();
            if( node != NULL ) {
                _wpi_sendmessage( node->hwnd, WM_CLOSE, 0, 0L );
            }
            break;

        case IMGED_CLOSEALL:
            CloseAllImages();
            break;

        case IMGED_HELP:
            IEHelpRoutine();
            break;

        case IMGED_HELP_SEARCH:
            IEHelpSearchRoutine();
            break;

        case IMGED_HELP_ON_HELP:
            IEHelpOnHelpRoutine();
            break;

        case IMGED_ABOUT:
#ifndef __OS2_PM__
            ai.owner = hwnd;
            ai.inst = Instance;
            ai.name = IEAllocRCString( WIE_ABOUTTEXT );
            ai.version = IEAllocRCString( WIE_ABOUTVERSION );
            ai.title = IEAllocRCString( WIE_ABOUTTITLE );
            DoAbout( &ai );
            if( ai.name != NULL ) {
                IEFreeRCString( ai.name );
            }
            if( ai.version != NULL ) {
                IEFreeRCString( ai.version );
            }
            if( ai.title != NULL ) {
                IEFreeRCString( ai.title );
            }
#endif
            break;

#ifndef __OS2_PM__
        case IMGED_DDE_UPDATE_PRJ:
            IEUpdateDDEEditSession();
            break;
#endif

        case IMGED_SAVE_AS:
            SaveFile( SB_SAVE_AS );
            break;

        case IMGED_SAVE:
            SaveFile( SB_SAVE );
            break;

        case IMGED_OPEN:
            if( !ImgedIsDDE ) {
                OpenImage( NULL );
            }
            break;

        case IMGED_CLEAR:
            ClearImage();
            break;

        case IMGED_NEWIMG:
            AddNewIcon();
            break;

        case IMGED_SELIMG:
            SelectIconImg();
            break;

        case IMGED_DELIMG:
            DeleteIconImg();
            break;

        case IMGED_UNDO:
            UndoOp();
            break;

        case IMGED_REDO:
            RedoOp();
            break;

        case IMGED_REST:
            RestoreImage();
            break;

        case IMGED_SNAP:
#ifndef __OS2_PM__
            SnapPicture();
#endif
            break;

        case IMGED_RIGHT:
        case IMGED_LEFT:
        case IMGED_UP:
        case IMGED_DOWN:
            ShiftImage( cmdid );
            break;

        case IMGED_FLIPHORZ:
        case IMGED_FLIPVERT:
            FlipImage( cmdid );
            break;

        case IMGED_ROTATECC:
        case IMGED_ROTATECL:
            RotateImage( cmdid );
            break;

        case IMGED_PASTE:
            PlaceAndPaste();
            break;

        case IMGED_COPY:
            IECopyImage();
            break;

        case IMGED_CUT:
            CutImage();
            break;

        case IMGED_COLOR:
            CheckPaletteItem( hmenu );
            break;

        case IMGED_VIEW:
            CheckViewItem( hmenu );
            break;

        case IMGED_TOOLBAR:
            CheckToolbarItem( hmenu );
            break;

        case IMGED_SQUARE:
            CheckSquareGrid( hmenu );
            break;

        case IMGED_SIZE:
            ChangeImageSize();
            break;

        case IMGED_GRID:
            CheckGridItem( hmenu );
            break;

        case IMGED_MAXIMIZE:
            MaximizeCurrentChild();
            break;

        case IMGED_SETTINGS:
            SelectOptions();
            break;

        case IMGED_2x2:
        case IMGED_3x3:
        case IMGED_4x4:
        case IMGED_5x5:
            checkBrushItem( hmenu, cmdid );
            break;

        case IMGED_CEDIT:
#ifndef __OS2_PM__
            EditColors();
#endif
            break;

        case IMGED_CRESET:
#ifndef __OS2_PM__
            RestoreColors();
#endif
            break;

        case IMGED_CSCREEN:
            ChooseBkColor();
            break;

        case IMGED_SCOLOR:
#ifndef __OS2_PM__
            SaveColorPalette();
#endif
            break;

        case IMGED_LCOLOR:
#ifndef __OS2_PM__
            if( LoadColorPalette() ) {
                _wpi_enablemenuitem( hmenu, IMGED_RCOLOR, TRUE, FALSE );
            }
#endif
            break;

        case IMGED_RCOLOR:
            RestoreColorPalette();
            break;

        case IMGED_FREEHAND:
        case IMGED_LINE:
        case IMGED_RECTO:
        case IMGED_RECTF:
        case IMGED_CIRCLEO:
        case IMGED_CIRCLEF:
        case IMGED_FILL:
        case IMGED_BRUSH:
        case IMGED_CLIP:
        case IMGED_HOTSPOT:
            SetToolType( cmdid );
            PushToolButton( cmdid );
            break;

        case IMGED_ARRANGE:
#ifndef __OS2_PM__
            SendMessage( ClientWindow, WM_MDIICONARRANGE, 0, 0L );
#endif
            break;

        case IMGED_TILE:
#ifndef __OS2_PM__
            SendMessage( ClientWindow, WM_MDITILE, MDITILE_VERTICAL, 0L );
#endif
            break;

        case IMGED_CASCADE:
#ifndef __OS2_PM__
            SendMessage( ClientWindow, WM_MDICASCADE, MDITILE_SKIPDISABLED, 0L );
#endif
            break;

        case IMGED_EXIT:
            _wpi_sendmessage( hwnd, WM_COMMAND, IMGED_CLOSEALL, 0L );

            if( _wpi_getfirstchild( _wpi_getclient( ClientWindow ) ) != NULL ) {
                break;
            }
#ifndef __OS2_PM__
            _wpi_destroywindow( _wpi_getframe( hwnd ) );
#else
            _wpi_sendmessage( hwnd, WM_CLOSE, 0, 0 );
#endif
            break;

        default:
#if 1
            return( _imgwpi_defframeproc( hwnd, ClientWindow, msg, wparam, lparam ) );
#else
            return( 0 );
#endif
        }
        return( 0 );

#ifndef __OS2_PM__
    case WM_COMPACTING:
        RelieveUndos();
        return 0;
#endif

    case WM_QUERYENDSESSION:
        if( _wpi_isiconic( _wpi_getframe( hwnd ) ) ) {
            if( ImgedConfigInfo.ismaximized ) {
                _wpi_maximizewindow( _wpi_getframe( hwnd ) );
            } else {
                _wpi_showwindow( _wpi_getframe( hwnd ), SW_SHOWNORMAL );
            }
        }
        _wpi_sendmessage( hwnd, WM_COMMAND, IMGED_CLOSEALL, 0L );

        if( _wpi_getfirstchild( _wpi_getclient( ClientWindow ) ) != NULL ) {
            return( 0 );
        }
        return( (WPI_MRESULT)1 );

    case WM_CLOSE:
        // wParam is non-zero if the DDE connection died
        if( !wparam && !ImgEdEnableMenuInput ) {
            // this prevents the user from closing the editor during
            // DDE initialization
            return( 0 );
        }
        _wpi_sendmessage( hwnd, WM_COMMAND, IMGED_CLOSEALL, 0L );
#ifdef __OS2_PM__
        return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) );
#else

        if( _wpi_getfirstchild( _wpi_getclient( ClientWindow ) ) != NULL ) {
            return( 0 );
        }
        window_destroyed = TRUE;
        _wpi_destroywindow( _wpi_getframe( hwnd ) );
        return( 0 );
#endif

    case WM_DESTROY:
#ifndef __OS2_PM__
        WWinHelp( HMainWindow, "resimg.hlp", HELP_QUIT, 0 );
#endif
        FiniStatusLine();
        CleanupClipboard();
        CleanupCursors();
        CloseToolBar();
        CloseFunctionBar();
        _wpi_deletefont( SmallFont );
        _wpi_postquitmessage( 0 );
        return( 0 );
    default:
        break;
    }
    return( _imgwpi_defframeproc( hwnd, ClientWindow, msg, wparam, lparam ) );

} /* ImgEdFrameProc */
Ejemplo n.º 20
0
void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
{
    SCH_SCREEN* screen = GetScreen();
    SCH_ITEM*   item = screen->GetCurItem();

    INSTALL_UNBUFFERED_DC( dc, m_canvas );

    // Allows block rotate operation on hot key.
    if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK )
    {
        screen->m_BlockLocate.SetCommand( BLOCK_ROTATE );
        HandleBlockEnd( &dc );
        return;
    }

    if( item == NULL )
    {
        // If we didn't get here by a hot key, then something has gone wrong.
        if( aEvent.GetInt() == 0 )
            return;

        EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();

        wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );

        item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::RotatableItems,
                                  aEvent.GetInt() );

        // Exit if no item found at the current location or the item is already being edited.
        if( (item == NULL) || (item->GetFlags() != 0) )
            return;
    }

    switch( item->Type() )
    {
    case SCH_COMPONENT_T:
        {
            SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( item );
            if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE )
                OrientComponent( CMP_ROTATE_CLOCKWISE );
            else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE )
                OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE );
            else
                wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) );

            if( m_autoplaceFields )
                component->AutoAutoplaceFields( GetScreen() );

            m_canvas->Refresh();

            break;
        }

    case SCH_TEXT_T:
    case SCH_LABEL_T:
    case SCH_GLOBAL_LABEL_T:
    case SCH_HIERARCHICAL_LABEL_T:
        m_canvas->MoveCursorToCrossHair();
        ChangeTextOrient( (SCH_TEXT*) item );
        m_canvas->Refresh();
        break;

    case SCH_FIELD_T:
        m_canvas->MoveCursorToCrossHair();
        RotateField( (SCH_FIELD*) item );
        if( item->GetParent()->Type() == SCH_COMPONENT_T )
        {
            // Now that we're moving a field, they're no longer autoplaced.
            SCH_COMPONENT *parent = static_cast<SCH_COMPONENT*>( item->GetParent() );
            parent->ClearFieldsAutoplaced();
        }
        m_canvas->Refresh();
        break;

    case SCH_BITMAP_T:
        RotateImage( (SCH_BITMAP*) item );
        break;

    case SCH_SHEET_T:
        if( !item->IsNew() )    // rotate a sheet during its creation has no sense
        {
            bool retCCW = ( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE );
            RotateHierarchicalSheet( static_cast<SCH_SHEET*>( item ), retCCW );
        }

        break;

    case SCH_JUNCTION_T:
    case SCH_NO_CONNECT_T:
        // these items are not rotated, because rotation does not change them.
        break;

    default:
        // Other items (wires...) cannot be rotated, at least during creation
        if( item->IsNew() )
            break;

        wxFAIL_MSG( wxString::Format( wxT( "Cannot rotate schematic item type %s." ),
                                      GetChars( item->GetClass() ) ) );
    }

    if( item->GetFlags() == 0 )
        screen->SetCurItem( NULL );
}
int  Luc_main_corner_crop(int argc,char ** argv){

    std::string aFullPattern, cornersTxt;
    //Reading the arguments
    ElInitArgMain
    (
        argc,argv,
        LArgMain()  << EAMC(aFullPattern,"Images Pattern")
                    << EAMC(cornersTxt,"Corner txt File"),
        LArgMain()
    );

    std::string aDir,aPatIm;
    SplitDirAndFile(aDir,aPatIm,aFullPattern);

    ELISE_fp::MkDirRec(aDir + "Croped_images/");

    cInterfChantierNameManipulateur * aICNM = cInterfChantierNameManipulateur::BasicAlloc(aDir);
    const std::vector<std::string> * aSetIm = aICNM->Get(aPatIm);

    std::vector<std::string> aVectIm=*aSetIm;
    int nbIm=aVectIm.size();

    vector<vector<Pt2dr> > Pts;
    vector<int> SzX, SzY;
    std::ifstream file(cornersTxt.c_str(), ios::in);
    for(int i=0 ; i<nbIm ; i++)
    {
        vector<Pt2dr> PtsIm(3);
        string name;
        file >> name >> PtsIm[0].x >> PtsIm[0].y >> name >> PtsIm[1].x >> PtsIm[1].y >> name >> PtsIm[2].x >> PtsIm[2].y;
        Pts.push_back(PtsIm);
        SzX.push_back((int)euclid(PtsIm[0], PtsIm[1])); SzY.push_back((int)euclid(PtsIm[2], PtsIm[1]));
    }

    file.close();
    cout<<Pts<<endl;
    Pt2di aCrop; int border=10;
    aCrop.x=min(*min_element(SzX.begin(), SzX.end())-2*border,*min_element(SzY.begin(), SzY.end())-2*border);
    aCrop.y=aCrop.x;
    //aCrop.x=*min_element(std::begin(SzX), std::end(SzX))-2*border;
    //aCrop.y=*min_element(std::begin(SzY), std::end(SzY))-2*border;
    cout<<"Cropping to : "<<aCrop.x<<" "<<aCrop.y<<endl;

    for(int i=0 ; i<nbIm ; i++)
    {
        double alpha=(atan((Pts[i][0].y-Pts[i][1].y)/(Pts[i][0].x-Pts[i][1].x))+atan(-(Pts[i][2].x-Pts[i][1].x)/(Pts[i][2].y-Pts[i][1].y)))/2;
        cout<<"Alpha = "<<alpha<<endl;
        RotateImage(alpha, aCrop, Pts[i], aDir, aVectIm[i]);
    }

    //Pt2dr P1,P2,P3;
    //P1.x= 795 ; P1.y= 1064;
    //P2.x= 7401; P2.y= 926 ;
    //P3.x= 7518; P3.y= 7598;
    //cout<<(P1.y-P2.y)/(P1.x-P2.x)<<endl;
    //cout<<atan((P1.y-P2.y)/(P1.x-P2.x))<<endl;
    //cout<<(P3.x-P2.x)/(P3.y-P2.y)<<endl;
    //cout<<atan((P3.x-P2.x)/(P3.y-P2.y))<<endl;
    //double aT1=atan((P1.y-P2.y)/(P1.x-P2.x));
    //double aT2=atan(-(P3.x-P2.x)/(P3.y-P2.y));
    //cout<<aT1<<" + "<<aT2<< " = " <<(aT1+aT2)<<endl;


    return 0;
}
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;
}