// Medit code for image morphing assignment, 15-412 spring 2001 // by Liu Ren #include #include #include #include #include #include #include #include #include //#include //#include #include #include "morphdata.h" #include #include #include #include #include #define IS_IN_IMGA 0 #define IS_IN_IMGB 1 #define IS_OUT_IMG 3 #define MOUSE_LEFT_BUTTON 1 #define MOUSE_MIDDLE_BUTTON 2 #define MOUSE_RIGHT_BUTTON 3 #define MOUSE_PRESSDRAG_ON 0 #define MOUSE_PRESSDRAG_OFF 1 #define BIG_VALUE 1e+3 #define CLOSE_LIMIT 0.04 static char usage[] ="\ Usage: medit [options] PICFILE1 PICFILE2 [lines_file]\n\ Allows generation and editing of line segments for morphing\n\ options:\n\ -zoom Z zoom picture by factor of Z (e.g. \"-zoom 2\" doubles)\n\ \n"; static GLuint texName[2]; // Define subclass of GL window class CMorphWindow : public Fl_Gl_Window { public: //int xdum,ydum; void draw(); int handle(int event); int AMinx,AMiny,AMaxx,AMaxy; int BMinx,BMiny,BMaxx,BMaxy; //Pic *img; int CurImg; int tmpSegId; int LeftMousePush; int LeftMouseDrag; int RightMousePush; int RightMouseDrag; public: CMorphWindow(int w,int h,const char *l=0); void SetAClipWindow(int minx,int miny,int maxx,int maxy); void SetBClipWindow(int minx,int miny,int maxx,int maxy); int GetClosePoint(double xcord,double ycord,int imgid,int& convert); void HandleMousePush(); void HandleMouseDrag(); void HandleMouseRelease(); inline int GetWhichImg(int x,int y){ if(x>=AMinx && x<=AMaxx && y>=AMiny && y<=AMaxy){ return IS_IN_IMGA; } if(x>=BMinx && x<=BMaxx && y>=BMiny && y<=BMaxy){ return IS_IN_IMGB; } return IS_OUT_IMG; } inline void GetImgACoord(double cordx, double cordy, int& imgx,int& imgy){ int imgwidth,imgheight; imgwidth = AMaxx-AMinx+1; imgheight = AMaxy-AMiny+1; imgx = (int)(cordx*imgwidth+AMinx-1+0.5); imgy = (int)((1-cordy)*imgheight+AMiny+0.5); }; inline void GetImgBCoord(double cordx, double cordy, int& imgx,int& imgy){ int imgwidth,imgheight; imgwidth = BMaxx-BMinx+1; imgheight = BMaxy-BMiny+1; imgx = (int)(cordx*imgwidth+BMinx-1+0.5); imgy = (int)((1-cordy)*imgheight+BMiny+0.5); }; inline void GetACoord(int imgx,int imgy,double& cordx, double& cordy){ cordx = 1.0*(imgx-AMinx+1)/(AMaxx-AMinx+1); cordy = 1.0-1.0*(imgy-AMiny+1)/(AMaxy-AMiny+1); if(cordx<0) cordx =0; if(cordx>1) cordx =1; if(cordy<0) cordy =0; if(cordy>1) cordy =1; } inline void GetBCoord(int imgx,int imgy,double& cordx, double& cordy){ cordx = 1.0*(imgx-BMinx+1)/(BMaxx-BMinx+1); cordy = 1.0-1.0*(imgy-BMiny+1)/(BMaxy-BMiny+1); if(cordx<0) cordx =0; if(cordx>1) cordx =1; if(cordy<0) cordy =0; if(cordy>1) cordy =1; } //void setImage(Pic *image); // float xoff, yoff, scale; }; // Global variables Fl_Window *fltkWin; Fl_Button *buttonTitle; Fl_Button *buttonLoad; Fl_Button *buttonSave; Fl_Button *buttonCrounchAway; Fl_Button *buttonQuit; Fl_Value_Slider *valueSliderWarpFrac; Fl_Value_Slider *valueSliderCrossFrac; Fl_Value_Input *valueInputA; Fl_Value_Input *valueInputB; Fl_Value_Input *valueInputP; Fl_Output *stringOutput; Fl_Choice *choiceAlg; CMorphWindow *pane; Fl_Menu_Item itemsAlg[] = { {"Your Morph"}, {"Their Morph"}, {0} }; //Fl_Scrollbar *hscroll; CMorphData *morphData; int CMorphWindow::GetClosePoint(double xcord,double ycord,int imgid,int& convert){ int i,tmpseg; double dist,tmpd; tmpseg = INVALID_SEG; dist = BIG_VALUE; for(i=0;i<(morphData->m_iNumSegs);i++){ if(morphData->m_dSegArr[i][8]==DELETED) continue; if (dist>(tmpd=(morphData->m_dSegArr[i][0+4*imgid]-xcord)* (morphData->m_dSegArr[i][0+4*imgid]-xcord)+ (morphData->m_dSegArr[i][1+4*imgid]-ycord)* (morphData->m_dSegArr[i][1+4*imgid]-ycord))) { dist=tmpd; tmpseg=i; convert=0; } if (dist>(tmpd=(morphData->m_dSegArr[i][2+4*imgid]-xcord)* (morphData->m_dSegArr[i][2+4*imgid]-xcord)+ (morphData->m_dSegArr[i][3+4*imgid]-ycord)* (morphData->m_dSegArr[i][3+4*imgid]-ycord))) { dist=tmpd; tmpseg=i; convert=1; } } if(distm_iWidth,morphData->m_iHeight,0,GL_RGB,GL_UNSIGNED_BYTE,morphData->m_pImgA); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,morphData->m_iWidth,morphData->m_iHeight,0,GL_RGB,GL_UNSIGNED_BYTE,morphData->m_pImgA); glBindTexture( GL_TEXTURE_2D, texName[1] ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,morphData->m_iWidth,morphData->m_iHeight,0,GL_RGB,GL_UNSIGNED_BYTE,morphData->m_pImgB); glEnable(GL_TEXTURE_2D); */ // Update scrollers /* int slidex = 100; int slidey = 100; if (slidex < 0) slidex = 0; if (slidey < 0) slidey = 0; int slidestep = 5; hscroll->range(0, slidex); hscroll->slider_size(slidestep/(float)slidex); */ /* vscroll->range(0, slidey); vscroll->slider_size(slidestep/(float)slidey); */ //glflush? } /* draw image, one scanline at a time */ glClear(GL_COLOR_BUFFER_BIT); /* glBindTexture(GL_TEXTURE_2D,texName[0]); glBegin(GL_QUADS); glTexCoord2f(0.0,0.0); glVertex2f(10.0,10.0); glTexCoord2f(1.0,0.0); glVertex2f(309.0,10.0); glTexCoord2f(1.0,1.0); glVertex2f(309.0,409.0); glTexCoord2f(0.0,1.0); glVertex2f(10.0,409.0); glEnd(); glBindTexture(GL_TEXTURE_2D,texName[1]); glBegin(GL_QUADS); glTexCoord2f(0.0,0.0); glVertex2f(320.0,10.0); glTexCoord2f(1.0,0.0); glVertex2f(619.0,10.0); glTexCoord2f(1.0,1.0); glVertex2f(619.0,409.0); glTexCoord2f(0.0,1.0); glVertex2f(320.0,409.0); glEnd(); GLenum errCode; const GLubyte *errString; errCode = glGetError(); if(errCode ==GL_INVALID_VALUE) printf("Error \n"); */ glRasterPos2i(10,10); glDrawPixels(morphData->m_iWidth,morphData->m_iHeight,GL_RGB,GL_UNSIGNED_BYTE,morphData->m_pImgA); glRasterPos2i(320,10); glDrawPixels(morphData->m_iWidth,morphData->m_iHeight,GL_RGB,GL_UNSIGNED_BYTE,morphData->m_pImgB); glColor3f(0.0, 1.0, 0.0); for(int i=0;i<(morphData->m_iNumSegs);i++){ if(morphData->m_dSegArr[i][8]==DELETED) continue; int ax1,ay1,bx1,by1; int ax2,ay2,bx2,by2; GetImgACoord(morphData->m_dSegArr[i][0], morphData->m_dSegArr[i][1],ax1,ay1); GetImgACoord(morphData->m_dSegArr[i][2], morphData->m_dSegArr[i][3],ax2,ay2); GetImgBCoord(morphData->m_dSegArr[i][4], morphData->m_dSegArr[i][5],bx1,by1); GetImgBCoord(morphData->m_dSegArr[i][6], morphData->m_dSegArr[i][7],bx2,by2); glBegin(GL_LINES); glVertex2i(ax1,ay1); glVertex2i(ax2,ay2); glVertex2i(bx1,by1); glVertex2i(bx2,by2); glEnd(); glPointSize(4); glBegin(GL_POINTS); glVertex2i(ax2,ay2); glVertex2i(bx2,by2); glEnd(); } glColor3f(1.0, 0.0, 0.0); int ax1,ay1,bx1,by1; int ax2,ay2,bx2,by2; int curid; curid = morphData->m_iCurSeg; if(curid!=INVALID_SEG){ GetImgACoord(morphData->m_dSegArr[curid][0], morphData->m_dSegArr[curid][1],ax1,ay1); GetImgACoord(morphData->m_dSegArr[curid][2], morphData->m_dSegArr[curid][3],ax2,ay2); GetImgBCoord(morphData->m_dSegArr[curid][4], morphData->m_dSegArr[curid][5],bx1,by1); GetImgBCoord(morphData->m_dSegArr[curid][6], morphData->m_dSegArr[curid][7],bx2,by2); glBegin(GL_LINES); glVertex2i(ax1,ay1); glVertex2i(ax2,ay2); glVertex2i(bx1,by1); glVertex2i(bx2,by2); glEnd(); glBegin(GL_POINTS); glVertex2i(ax2,ay2); glVertex2i(bx2,by2); glEnd(); } // morphData->SaveLinesFile("dummy.lines"); //errString = gluErrorString(errCode); //fprintf(stderr,"Open GL %s\n",errString); /*if (img) { for (int y = 0; y < img->ny; y++) { glRasterPos2i(0, y); glDrawPixels(img->nx, 1, GL_RGB, GL_UNSIGNED_BYTE, &(PIC_PIXEL(img, 0, y, 0)) ); } } */ Fl_Gl_Window::draw(); // glFlush(); } void CMorphWindow::HandleMousePush(){ int ev_x,ev_y; ev_x = Fl::event_x() ; ev_y = Fl::event_y() ; // if(Fl::event_button()== FL_LEFT_MOUSE){ if(Fl::event_button()==MOUSE_LEFT_BUTTON){ int whichimg; int imgx,imgy; imgx = (int)(ev_x); imgy = (int)(h()-ev_y-1); whichimg=GetWhichImg(imgx,imgy); if(whichimg!=IS_OUT_IMG){ LeftMousePush = MOUSE_PRESSDRAG_ON; double cordx,cordy; if (whichimg==IS_IN_IMGA){ GetACoord(imgx,imgy,cordx,cordy); printf("Left Mouse Press in A: %lf %lf. \n",cordx,cordy); CurImg = IS_IN_IMGA; }else{ GetBCoord(imgx,imgy,cordx,cordy); printf("Left Mouse Press in B: %lf %lf \n",cordx,cordy); CurImg = IS_IN_IMGB; } int newsegid; newsegid =morphData->GetNewSegid(); if(newsegid == INVALID_SEG){ LeftMousePush = MOUSE_PRESSDRAG_OFF; printf("Too many line segments,please delete some.\n"); }else{ morphData->m_dSegArr[newsegid][0] = cordx; morphData->m_dSegArr[newsegid][1] = cordy; morphData->m_dSegArr[newsegid][4] = cordx; morphData->m_dSegArr[newsegid][5] = cordy; tmpSegId = newsegid; } } // fprintf(stderr, "Left Mouse click at: (%.2f, %.2f)\n", ev_x, ev_y); redraw(); // }else if(Fl::event_button()==FL_RIGHT_MOUSE){ }else if(Fl::event_button()==MOUSE_RIGHT_BUTTON){ int whichimg; int imgx,imgy; imgx = (int)(ev_x); imgy = (int)(h()-ev_y-1); whichimg=GetWhichImg(imgx,imgy); if(whichimg!=IS_OUT_IMG){ RightMousePush = MOUSE_PRESSDRAG_ON; double cordx,cordy; if (whichimg==IS_IN_IMGA){ GetACoord(imgx,imgy,cordx,cordy); printf("Rright Mouse Press in A: %lf %lf. \n",cordx,cordy); CurImg = IS_IN_IMGA; }else{ GetBCoord(imgx,imgy,cordx,cordy); printf("Right Mouse Press in B: %lf %lf \n",cordx,cordy); CurImg = IS_IN_IMGB; } tmpSegId=GetClosePoint(cordx,cordy,CurImg,morphData->m_iSegInv); if(tmpSegId == INVALID_SEG){ RightMousePush = MOUSE_PRESSDRAG_OFF; CurImg = IS_OUT_IMG; morphData->m_iSegInv = 0; printf("No closer line segments,please click closer to the line segment.\n"); } } // fprintf(stderr, "Left Mouse click at: (%.2f, %.2f)\n", ev_x, ev_y); redraw(); } } void CMorphWindow::HandleMouseRelease(){ int ev_x,ev_y; ev_x = Fl::event_x() ; ev_y = Fl::event_y() ; int imgx,imgy; double cordx,cordy; imgx = (int)(ev_x); imgy = (int)(h()-ev_y-1); // if(Fl::event_button()==FL_LEFT_MOUSE){ if(Fl::event_button()== MOUSE_LEFT_BUTTON){ if(LeftMouseDrag == MOUSE_PRESSDRAG_ON){ if(CurImg == IS_IN_IMGA){ GetACoord(imgx,imgy,cordx,cordy); printf("Left Mouse Release in A: %lf %lf \n",cordx,cordy); }else{ GetBCoord(imgx,imgy,cordx,cordy); printf("Left Mouse Release in B: %lf %lf \n",cordx,cordy); } morphData->m_dSegArr[tmpSegId][2] = cordx; morphData->m_dSegArr[tmpSegId][3] = cordy; morphData->m_dSegArr[tmpSegId][6] = cordx; morphData->m_dSegArr[tmpSegId][7] = cordy; morphData->m_iLineChange = LINE_CHANGE; CurImg = IS_OUT_IMG; tmpSegId = INVALID_SEG; LeftMouseDrag = MOUSE_PRESSDRAG_OFF; LeftMousePush = MOUSE_PRESSDRAG_OFF; }else{ printf("in left mouse click state.\n"); int curseg; curseg = morphData->m_iCurSeg; if((Fl::event_state()&FL_SHIFT)&&(curseg!=INVALID_SEG)){ morphData->m_dSegArr[curseg][8] = DELETED; morphData->m_iLineChange = LINE_CHANGE; } CurImg = IS_OUT_IMG; tmpSegId = INVALID_SEG; morphData->m_iCurSeg=INVALID_SEG; //LeftMouseDrag = MOUSE_PRESSDRAG_OFF; LeftMousePush = MOUSE_PRESSDRAG_OFF; } // fprintf(stderr, "Left Mouse click at: (%.2f, %.2f)\n", ev_x, ev_y); redraw(); // }else if(Fl::event_button()==FL_RIGHT_MOUSE){ // }else if(Fl::event_button()==FL_BUTTON3){ }else if(Fl::event_button()==MOUSE_RIGHT_BUTTON){ if(RightMouseDrag == MOUSE_PRESSDRAG_ON){ if(CurImg == IS_IN_IMGA){ GetACoord(imgx,imgy,cordx,cordy); printf("Right Mouse Release in A: %lf %lf \n",cordx,cordy); }else{ GetBCoord(imgx,imgy,cordx,cordy); printf("Right Mouse Release in B: %lf %lf \n",cordx,cordy); } morphData->m_dSegArr[tmpSegId][CurImg*4+(morphData->m_iSegInv)*2] = cordx; morphData->m_dSegArr[tmpSegId][CurImg*4+(morphData->m_iSegInv)*2+1] = cordy; morphData->m_iLineChange = LINE_CHANGE; morphData->m_iSegInv =0; morphData->m_iCurSeg = tmpSegId; CurImg = IS_OUT_IMG; tmpSegId = INVALID_SEG; RightMouseDrag = MOUSE_PRESSDRAG_OFF; RightMousePush = MOUSE_PRESSDRAG_OFF; }else{ printf("in right mouse click state.\n"); morphData->m_iCurSeg = tmpSegId; CurImg = IS_OUT_IMG; tmpSegId = INVALID_SEG; //LeftMouseDrag = MOUSE_PRESSDRAG_OFF; RightMousePush = MOUSE_PRESSDRAG_OFF; } // fprintf(stderr, "Left Mouse click at: (%.2f, %.2f)\n", ev_x, ev_y); redraw(); } } void CMorphWindow::HandleMouseDrag(){ int ev_x,ev_y; ev_x = Fl::event_x() ; ev_y = Fl::event_y() ; int imgx,imgy; double cordx,cordy; imgx = (int)(ev_x); imgy = (int)(h()-ev_y-1); if(Fl::event_state()&FL_BUTTON1){ printf("We are in Left Button Down Drag State.\n"); if(LeftMousePush == MOUSE_PRESSDRAG_ON){ LeftMouseDrag = MOUSE_PRESSDRAG_ON; morphData->m_dSegArr[tmpSegId][8] = EXISTING; if((tmpSegId+1)>morphData->m_iNumSegs){ morphData->m_iNumSegs++; } if(CurImg == IS_IN_IMGA){ GetACoord(imgx,imgy,cordx,cordy); printf("Left Mouse Drag in A: %lf %lf \n",cordx,cordy); }else{ GetBCoord(imgx,imgy,cordx,cordy); printf("Left Mouse Drag in B: %lf %lf \n",cordx,cordy); } morphData->m_dSegArr[tmpSegId][2] = cordx; morphData->m_dSegArr[tmpSegId][3] = cordy; morphData->m_dSegArr[tmpSegId][6] = cordx; morphData->m_dSegArr[tmpSegId][7] = cordy; morphData->m_iLineChange = LINE_CHANGE; morphData->m_iCurSeg = tmpSegId; } }else if(Fl::event_state()&FL_BUTTON3){ printf("We are in Right Button Down Drag State.\n"); if(RightMousePush == MOUSE_PRESSDRAG_ON){ RightMouseDrag = MOUSE_PRESSDRAG_ON; if(CurImg == IS_IN_IMGA){ GetACoord(imgx,imgy,cordx,cordy); printf("Right Mouse Drag in A: %lf %lf \n",cordx,cordy); }else{ GetBCoord(imgx,imgy,cordx,cordy); printf("Right Mouse Drag in B: %lf %lf \n",cordx,cordy); } morphData->m_dSegArr[tmpSegId][CurImg*4+(morphData->m_iSegInv)*2] = cordx; morphData->m_dSegArr[tmpSegId][CurImg*4+(morphData->m_iSegInv)*2+1] = cordy; if(Fl::event_state()&FL_SHIFT){ int otherimg; otherimg = 1-CurImg; morphData->m_dSegArr[tmpSegId][otherimg*4+(morphData->m_iSegInv)*2] = cordx; morphData->m_dSegArr[tmpSegId][otherimg*4+(morphData->m_iSegInv)*2+1] = cordy; } morphData->m_iCurSeg = tmpSegId; morphData->m_iLineChange = LINE_CHANGE; }else{ printf("Invalid drag, not start from inside of a image.\n"); } }else{ printf(" Where are we?middle button drag?\n"); } redraw(); } // Handle events int CMorphWindow::handle(int event) { // float ev_x, ev_y; switch(event) { case FL_PUSH: HandleMousePush(); break; case FL_DRAG: HandleMouseDrag(); break; case FL_RELEASE: printf("goto release state.\n"); HandleMouseRelease(); break; default: ; } Fl_Gl_Window::handle(event); return 1; } /*void CMorphWindow::setImage(Pic *image) { img = image; redraw(); } */ // Scroller callbacks /*void hscrollcb(Fl_Scrollbar* scroll) { pane->xoff = (float)scroll->value(); //pane->invalidate(); //pane->redraw(); } */ /*void vscrollcb(Fl_Scrollbar* scroll) { pane->yoff = (float)scroll->value(); pane->invalidate(); pane->redraw(); } */ void buttonQuitCB(Fl_Button *button,void *){ if(morphData->m_iLineChange ==LINE_CHANGE){ int ask; ask = fl_ask("Your morph lines file is not saved,really quit?"); if(ask==1){ exit(0); } }else{ exit(0); } } void buttonCrounchAwayCB(Fl_Button *button,void *){ } void choiceAlgCB(Fl_Choice *pchoice,void *dum){ morphData->m_iMorphAlg = pchoice->value(); printf("Morph Algorithm changes to %d.\n",morphData->m_iMorphAlg); } void buttonCB(Fl_Button *button,void *){ char * filename; int iovalue; if (button==buttonLoad){ filename = fl_file_chooser("Select lines filename","*.*",0); if(filename!=NULL){ iovalue = morphData->GetLinesFile(filename); if(iovalue == IO_SUCCESS){ stringOutput->value(filename); pane->redraw(); } } }else if(button==buttonSave){ filename = fl_file_chooser("Select lines filename","*.*",0); if(filename!=NULL){ iovalue = morphData->SaveLinesFile(filename); if(iovalue == IO_SUCCESS){ stringOutput->value(filename); pane->redraw(); } } }else{ printf("invalid button.\n"); } } void sliderWarpFracCB(Fl_Value_Slider *pslider,long dum){ morphData->m_dWarpFrac = pslider->value(); printf("Warp Fraction changed to %lf.\n",morphData->m_dWarpFrac); } void sliderCrossFracCB(Fl_Value_Slider *pslider,long dum){ morphData->m_dDissFrac = pslider->value(); printf("Cross-dissolve Fraction changed to %lf.\n",morphData->m_dDissFrac); } void valueInputCB(Fl_Value_Input *pValueInput,long dum){ if (pValueInput==valueInputA){ morphData->m_dParaA = pValueInput->value(); printf("A changed %lf.\n",morphData->m_dParaA); }else if(pValueInput==valueInputB){ morphData->m_dParaB = pValueInput->value(); printf("B changed %lf.\n",morphData->m_dParaB); }else if(pValueInput==valueInputP){ morphData->m_dParaP = pValueInput->value(); printf("P changed %lf.\n",morphData->m_dParaP); }else{ printf("Invalid input CB.\n"); } morphData->m_iLineChange = LINE_CHANGE; } int main (int argc, char **argv) { morphData = new CMorphData(); int count; int i; count = 1; int rwstate; rwstate = IO_SUCCESS; int ha,wa,hb,wb; for (i=1;im_dZoom = atof(argv[++i]); else if (argv[i][0]=='-') {printf("ignoring option: %s\n", argv[i]); printf(usage); } else switch(count++) { case 1: rwstate = morphData->GetImgA(argv[i],ha,wa); break; case 2: rwstate = morphData->GetImgB(argv[i],hb,wb); break; case 3: rwstate = morphData->GetLinesFile(argv[i]); break; default: printf(usage); exit(1); } if(rwstate==IO_FAIL) { printf(usage); exit(1); } } if (count<3) {printf(usage); exit(1);} if(ha!=hb || wa!=wb){ printf("The two picture files must be the same dimension.\n"); printf("Use a tool like pnmscale or xv to rescale if desired.\n"); exit(0); }else{ morphData->SetImageDim(ha,wa); } if(ha>600|| wa>600) { printf("Image is too large.\n"); exit(1); } int widthWin, heightWin; widthWin = 3*wa+30; if(widthWin<950) widthWin = 950; heightWin = 200+ha+20; fltkWin = new Fl_Window(widthWin, heightWin, "Medit"); // fltkWin->mode(FL_RGB |FL_DOUBLE | FL_ALPHA); // hscroll = new Fl_Scrollbar(0,heightWin-200+1, widthWin, 200); //hscroll->type(1); //hscroll->callback((Fl_Callback*)hscrollcb); //hscroll->step(5); // vscroll = new Fl_Scrollbar(640, 0, 20, 480); //vscroll->type(0); //vscroll->callback((Fl_Callback*)vscrollcb); //hscroll->step(5); { pane = new CMorphWindow(widthWin, heightWin-200, "Morph"); pane->mode(FL_RGB |FL_DOUBLE | FL_ALPHA); pane->SetAClipWindow(10,10,10+wa-1,10+ha-1); pane->SetBClipWindow(20+wa,10,20+wa+wa-1,10+ha-1); buttonTitle = new Fl_Button(10,heightWin-200+1+25,95,40,"Medit"); buttonTitle->box(FL_FLAT_BOX); buttonTitle->labeltype(FL_ENGRAVED_LABEL); buttonTitle->labelsize(30); buttonTitle->labelcolor(4); //buttonTitle->align(20); buttonLoad = new Fl_Button(5,heightWin-200+1+100,120,30,"Load Lines File"); buttonLoad->labelsize(12); buttonLoad->callback((Fl_Callback *)buttonCB); buttonSave = new Fl_Button(5,heightWin-200+1+150,120,30,"Save Lines File"); buttonSave->labelsize(12); buttonSave->callback((Fl_Callback *)buttonCB); valueSliderWarpFrac = new Fl_Value_Slider(170,heightWin-200+1+15,200,20,"Warp Fraction"); valueSliderWarpFrac->type(FL_HOR_NICE_SLIDER); valueSliderWarpFrac->minimum(0.0); valueSliderWarpFrac->maximum(1.0); valueSliderWarpFrac->step(0.01); valueSliderWarpFrac->labelsize(12); valueSliderWarpFrac->value(WARP_FRACTION_INIT); valueSliderWarpFrac->callback((Fl_Callback*)sliderWarpFracCB,(void*)(0)); valueSliderCrossFrac = new Fl_Value_Slider(170,heightWin-200+1+65,200,20,"Cross-dissolve Fraction"); valueSliderCrossFrac->type(FL_HOR_NICE_SLIDER); valueSliderCrossFrac->minimum(0.0); valueSliderCrossFrac->maximum(1.0); valueSliderCrossFrac->step(0.01); valueSliderCrossFrac->labelsize(12); valueSliderCrossFrac->value(DISSOLVE_FRACTION_INIT); valueSliderCrossFrac->callback((Fl_Callback*)sliderCrossFracCB,(void*)(0)); valueInputA = new Fl_Value_Input(170,heightWin-200+1+115,40,20,"A:"); //valueInputA->type(Fl_VALUE_INPUT); valueInputA->labelsize(12); valueInputA->value(A_INIT); valueInputA->callback((Fl_Callback*)valueInputCB,(void*)(0)); valueInputB = new Fl_Value_Input(240,heightWin-200+1+115,40,20,"B:"); //valueInputA->type(Fl_VALUE_INPUT); valueInputB->labelsize(12); valueInputB->value(B_INIT); valueInputB->callback((Fl_Callback*)valueInputCB,(void*)(0)); valueInputP = new Fl_Value_Input(310,heightWin-200+1+115,40,20,"P:"); //valueInputA->type(Fl_VALUE_INPUT); valueInputP->labelsize(12); valueInputP->value(P_INIT); valueInputP->callback((Fl_Callback*)valueInputCB,(void*)(0)); stringOutput = new Fl_Output(260,heightWin-200+1+115+50,500,20,"Current Lines File"); stringOutput->labelsize(12); stringOutput->value(morphData->m_cLinesFileName); choiceAlg = new Fl_Choice(450,heightWin-200+1+15,180,30,"Algorithm:"); choiceAlg->labelsize(12); choiceAlg->callback((Fl_Callback*)choiceAlgCB); choiceAlg->when(1); choiceAlg->menu(itemsAlg); choiceAlg->value(0); choiceAlg->box(FL_ROUND_UP_BOX); buttonCrounchAway = new Fl_Button(450,heightWin-200+1+55,125,30,"Crounch Away"); buttonCrounchAway->labelsize(12); buttonCrounchAway->callback((Fl_Callback *)buttonCrounchAwayCB); buttonQuit = new Fl_Button(450,heightWin-200+1+95,125,30,"Quit"); buttonQuit->labelsize(12); buttonQuit->callback((Fl_Callback *)buttonQuitCB); // Read in input image /*if (argc > 1) { Pic *img = tiff_read(argv[1], NULL); if(!img) { printf("Unable to open input file '%s'\n", argv[1]); } else { printf("Read a %dx%d TIFF image (%d bytes per pixel)\n", img->nx, img->ny, img->bpp); pane->setImage(img); } } else { fprintf(stderr, "Usage: mosaic img.tif\n"); exit(1); } */ //fltkWin->resizable(pane); } fltkWin->end(); fltkWin->show(); // pane->draw(); return Fl::run(); }