BmpArray * RasterSaccade::Run( int pRunFor, int & pSaccadesCompleted, int pSaccadesRequested ) { // RasterSaccade is used during learning as of version 1.3.3 unsigned int minRow, minCol, height, width; BmpArray *lTemp; lTemp = cOrigPixArray; cOrigPixArray = cShiftedPixArray; cShiftedPixArray = lTemp; FindImageBoundaries(*cOrigPixArray, minRow, minCol, height, width); //int lLimit = 0; //if ( pSaccadesRequested == -1 ) //{ // // do all // lLimit = ( cCoveredImageSide - height + 1 ) * ( cCoveredImageSide - width + 1 ); //} //else //{ // lLimit = pSaccadesRequested; //} //generate all possible shifts of the image pSaccadesCompleted = 0; unsigned i, j; //i, j - upper left corner of image rectangle for(i = 0; i <= cCoveredImageSide - height; i++) //move only within covered area { for(j = 0; j <= cCoveredImageSide - width; j++) { //all possible shifts, including beyond image boundaries //for(i = 1-height; i < (int)CoveredImageSide; i++) //move only within covered area // for(j = 1-width; j < (int)CoveredImageSide; j++){ //if something was drawn in the image area if(ShiftImage(cOrigPixArray, minRow, minCol, height, width, i, j, cShiftedPixArray)) { emit VisionService(cShiftedPixArray, pRunFor); } pSaccadesCompleted++; if ( pSaccadesCompleted == pSaccadesRequested ) // this will never be true if requesting -1 saccades { break; } // Save some shifting; lTemp = cOrigPixArray; cOrigPixArray = cShiftedPixArray; cShiftedPixArray = lTemp; // don't actually need the data! // But now we have to get the boundaries again. FindImageBoundaries(*cOrigPixArray, minRow, minCol, height, width); } if ( pSaccadesCompleted == pSaccadesRequested ) // this will never be true if requesting -1 saccades { break; } } return cShiftedPixArray; };
int cutTheFrame ( Image *dest, Image *src, int width, int height, int showprogress ) { int xoff, yoff; if( width > src->width || height > src->height ) { PrintError("Image smaller than Rectangle to cut"); return -1; } if( getFrame( src, &xoff, &yoff, width, height, showprogress ) == 0 ) { TrformStr TrCrop; memcpy( dest, src, sizeof( Image ) ); dest->width = width; dest->height = height; dest->bytesPerLine = dest->width * dest->bitsPerPixel/8; dest->dataSize = dest->height * dest->bytesPerLine ; dest->data = (unsigned char**) mymalloc( (size_t)dest->dataSize ); if( dest->data == NULL ) { PrintError("Could not allocate %ld bytes", dest->dataSize ); return -1; } memset(&TrCrop, 0, sizeof(TrformStr)); TrCrop.src = src; TrCrop.dest = dest; TrCrop.success = 0; ShiftImage( &TrCrop, xoff, yoff); if( TrCrop.success == 1 ) { return 0; } else { myfree( (void**)dest->data ); return -1; } } else return -1; }
BmpArray * PingPongSaccade::Run( int pRunFor, int & pSaccadesCompleted, int pSaccadesRequested ) { // Make calling convention same as for RasterSaccade int lSaccadesRequested = pSaccadesRequested; if ( pSaccadesRequested == -1 ) { lSaccadesRequested = 0; } unsigned int minRow, minCol, height, width; BmpArray *lTemp; lTemp = cOrigPixArray; cOrigPixArray = cShiftedPixArray; cShiftedPixArray = lTemp; pSaccadesCompleted = 0; FindImageBoundaries(*cOrigPixArray, minRow, minCol, height, width); // Always emit at least one image (for 0 saccades) emit VisionService(cShiftedPixArray, pRunFor); //generate all possible shifts of the image unsigned i, j; //i, j - upper left corner of image rectangle unsigned row = minRow, col = minCol; int deltaRow = -1, deltaCol = -1; if ( row+height == cCoveredImageSide ) { deltaRow = 1; } else { deltaRow = -1; } if ( col+width == cCoveredImageSide ) { deltaCol = 1; } else { deltaCol = -1; } for(i = 0; i < lSaccadesRequested; i++) { if ( height != cImageSide ) { if(row == 0 || row+height == cCoveredImageSide)//bounce off boundaries deltaRow = -deltaRow; //assume height, width < CoveredImageSide row += deltaRow; } if ( width != cImageSide ) { if(col == 0 || col+width == cCoveredImageSide) // deltaCol = -deltaCol; col += deltaCol; } ShiftImage(cOrigPixArray, minRow, minCol, height, width, row, col, cShiftedPixArray); emit VisionService(cShiftedPixArray, pRunFor); pSaccadesCompleted++; // Save some shifting; lTemp = cOrigPixArray; cOrigPixArray = cShiftedPixArray; cShiftedPixArray = lTemp; // don't actually need the data! // But now we have to get the boundaries again. FindImageBoundaries(*cOrigPixArray, minRow, minCol, height, width); } return cShiftedPixArray; };
/* * 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 */
int main(int argc, char **argv) { int nx = 512; int ny = 512; int nxp; int nyp; int na = 128; int nb = 128; int *ix; int *iy; int nr = 1000; Real x; Real **hst; Real **image; Real **pimage; Real **wimage; Real **fimage; Real **fimage_hr; Real **fimage_lr; Real **fimage_a; Real **fimage_b; Real **cimage; Real **timage; Real **kernel; Real **kb; Real **kc; Real *amp_a; Real *amp_b; FILE *fp; int n_iter; Real sigma_a = 0.01; Real sigma_b = 0.001; Lucy L; #ifdef HST n_iter = 1; image = LoadHST(&nx,&ny,&nxp,&nyp); na = nx; nb = ny; printf("nx = %d, ny = %d\n",nx,ny); #else n_iter = 20; image = MakeImage(nx,ny); wimage = MakeWrongImage(nx,ny); set_rng_integer_seed(10209); ix = MakeRandomIndices(nr,0.1*nx,nx-0.1*nx); set_rng_integer_seed(7493); iy = MakeRandomIndices(nr,0.1*ny,ny-0.1*ny); set_rng_uniform_seed(12930); amp_a = MakeRandomAmplitudes(nr, 0.1, 10.0); set_rng_uniform_seed(320943); amp_b = MakeRandomAmplitudes(nr, 0.5, 5.0); fimage_a = MakeFakeImage(nx,ny,ix,iy,amp_a,nr); fimage_b = MakeFakeImage(nx,ny,ix,iy,amp_b,nr); #endif printf("HERE!\n"); /* make low-res kernel */ //kernel = MakeKernel(nx,ny,sigma_a); //printf("HERE!\n"); //fflush(stdout); //kb = RebinImage(kernel,nx,ny,nx,ny); kernel = MakeKernel(nx,ny,sigma_a); kb = ShiftImage(kernel,nx,ny); //kernel = MakeKernel(na,nb,sigma_a); //kb = RebinImage(kernel,na,nb,nx,ny); printf("HERE!\n"); //deallocate_2d_array(kernel,na,nb); /* make high-res kernel */ //kernel = MakeKernel(nx,ny,sigma_b); //kc = RebinImage(kernel,nx,ny,nx,ny); //kernel = MakeKernel(na,nb,sigma_b); //kc = RebinImage(kernel,na,nb,nx,ny); //kc = MakeKernel(nx,ny,sigma_b); printf("HERE (LAST)!\n"); /* initialize the cuda convolution */ initialize_cuda_convolve_2d(nx,ny); /* blur image to make "observed" */ #ifdef HST printf("nx = %d, ny = %d\n",nx,ny); cimage = cuda_convolve_2d(image, kb, nx, ny); #else cimage = cuda_convolve_2d(fimage_a, kb, nx, ny); pimage = cuda_convolve_2d(fimage_b, kc, nx, ny); timage = cuda_convolve_2d(fimage_a, kc, nx, ny); #endif //pimage = cuda_convolve_2d(image, kc, nx, ny); //pimage = cuda_convolve_2d(wimage, kc, nx, ny); /*load image an kernel*/ L.LoadImage( cimage, nx, ny); L.LoadKernel( kb, nx, ny); #ifdef HST pimage = ModulateImage( image, nx, ny); L.LoadPriorImage( pimage, nx, ny); #else L.LoadPriorImage( pimage, nx, ny); #endif /*perform n_iterations of deconvolution*/ #ifndef PRIOR L.Deconvolve(n_iter); #else L.DeconvolveWithPrior(n_iter); #endif #ifdef HST fp = fopen("hst.dat","w"); #else fp = fopen("out.dat","w"); #endif fwrite(&nx,1,sizeof(int),fp); fwrite(&ny,1,sizeof(int),fp); printf("image %e %e\n",image[0][0],image[0][1]); for(int i=0;i<nx;i++) for(int j=0;j<ny;j++) #ifdef HST fwrite(&image[i][j],1,sizeof(Real),fp); #else fwrite(&fimage_a[i][j],1,sizeof(Real),fp); #endif for(int i=0;i<nx;i++) for(int j=0;j<ny;j++) fwrite(&L.phi_tilde[i][j],1,sizeof(Real),fp); //fwrite(&cimage[i][j],1,sizeof(Real),fp); for(int i=0;i<nx;i++) for(int j=0;j<ny;j++) fwrite(&L.phi_r[i][j],1,sizeof(Real),fp); for(int i=0;i<nx;i++) for(int j=0;j<ny;j++) fwrite(&L.psi_0[i][j],1,sizeof(Real),fp); for(int i=0;i<nx;i++) for(int j=0;j<ny;j++) fwrite(&L.psi_r[i][j],1,sizeof(Real),fp); for(int i=0;i<nx;i++) for(int j=0;j<ny;j++) fwrite(&L.prior_r[i][j],1,sizeof(Real),fp); for(int i=0;i<nx;i++) for(int j=0;j<ny;j++) #ifdef HST fwrite(&image[i][j],1,sizeof(Real),fp); #else fwrite(&timage[i][j],1,sizeof(Real),fp); //fwrite(&pimage[i][j],1,sizeof(Real),fp); #endif for(int i=0;i<nx;i++) for(int j=0;j<ny;j++) fwrite(&kb[i][j],1,sizeof(Real),fp); #ifndef HST fwrite(&nr,1,sizeof(int),fp); fwrite(&ix[0],nr,sizeof(int),fp); fwrite(&iy[0],nr,sizeof(int),fp); fwrite(&_a[0],nr,sizeof(Real),fp); fwrite(&_b[0],nr,sizeof(Real),fp); #endif fclose(fp); /* clean up */ destroy_cuda_convolve(); return 0; }
void correct (TrformStr *TrPtr, cPrefs *prefs) { int i=0,j,k, kstart, kend, kdone, color; double scale_params[2]; // scaling factors for resize; double shear_params[2]; // shear values double radial_params[6]; // coefficients for polynomial correction (0,...3) // and source width/2 (4) and correctionradius (5) double lum_params[2]; // parameters to correct luminance variation struct fDesc stack[10]; // Parameters for execute stack function struct fDesc stackinv[10]; // Parameters for execute stack function int destwidth, destheight; int xoff = 0, yoff = 0; int sizesqr; double xdoff, ydoff; Image im, *dest, *src; fDesc fD; fDesc fDinv; im.data = NULL; src = TrPtr->src; dest = TrPtr->dest; // Apply filters, if required TrPtr->success = 1; if( prefs->luminance ) { destwidth = TrPtr->src->width; destheight = TrPtr->src->height; // Allocate memory for destination image // If no further Xform: simply use SetDest if( !( prefs->resize || prefs->shear || prefs->horizontal || prefs->vertical || prefs->radial || prefs->cutFrame || prefs->fourier) ) { if( SetDestImage(TrPtr, destwidth, destheight) != 0 ) { TrPtr->success = 0; PrintError( "Not enough Memory."); return; } } else // Further Xform requested: use separate new image { memcpy( &im, TrPtr->src, sizeof(Image) ); im.data = (unsigned char**) mymalloc( (size_t)im.dataSize ); if( im.data == NULL ) { TrPtr->success = 0; PrintError( "Not enough Memory."); return; } TrPtr->dest = &im; } // JMW 2003/08/25 Use the smaller of the width or height to // calculate luminance so that the same change is made to portrait and // landscape images. // MRDL 2003/08/25 Makes behavior consistent with lens distortion correction // algorithm if( TrPtr->src->width < TrPtr->src->height ) sizesqr = (int)((TrPtr->src->width/2.0) * (TrPtr->src->width/2.0)); else sizesqr = (int)((TrPtr->src->height/2.0) * (TrPtr->src->height/2.0)); if( prefs->lum_params[0] == prefs->lum_params[1] && prefs->lum_params[1] == prefs->lum_params[2] ) // Color independent { lum_params[0] = - prefs->lum_params[0] / sizesqr; lum_params[1] = prefs->lum_params[0] / 2.0 ; if( TrPtr->success != 0 ) { filter( TrPtr, radlum, radlum16, (void*) lum_params, 0 ); } } else // Color dependent { for(k=1; k<4; k++) { lum_params[0] = - prefs->lum_params[k-1] / sizesqr; lum_params[1] = prefs->lum_params[k-1] / 2.0 ; if( TrPtr->success != 0 ) { filter( TrPtr, radlum, radlum16, (void*) lum_params, k ); } } } } if( TrPtr->success && prefs->fourier ) // Fourier filtering required { if( prefs->luminance ) { CopyImageData( src, &im ); TrPtr->src = src; } if( prefs->fourier_mode == _fresize ) { if( prefs->width == 0 && prefs->height == 0 ) { TrPtr->success = 0; PrintError( "Zero Destination Image Size" ); return; } if( prefs->width ) destwidth = prefs->width; else destwidth = (int)((double)TrPtr->src->width * (double)prefs->height / (double)TrPtr->src->height); if( prefs->height) destheight = prefs->height; else destheight = (int)((double)TrPtr->src->height * (double)prefs->width / (double)TrPtr->src->width); } else { destwidth = TrPtr->src->width; destheight = TrPtr->src->height; } // Allocate memory for destination image // If no further Xform: simply use SetDest if( !( prefs->resize || prefs->shear || prefs->horizontal || prefs->vertical || prefs->radial || prefs->cutFrame ) ) { if( SetDestImage(TrPtr, destwidth, destheight) != 0 ) { TrPtr->success = 0; PrintError( "Not enough Memory."); return; } } else // Further Xform requested: use separate new image { if( prefs->luminance ) // since then we have allocated im already { if( im.data ) myfree( (void**)im.data ); } memcpy( &im, TrPtr->src, sizeof(Image) ); im.width = destwidth; im.height = destheight; im.bytesPerLine = im.width * im.bitsPerPixel/8; im.dataSize = im.height * im.bytesPerLine; im.data = (unsigned char**) mymalloc( (size_t)im.dataSize ); if( im.data == NULL ) { TrPtr->success = 0; PrintError( "Not enough Memory."); return; } TrPtr->dest = &im; } fourier( TrPtr, prefs ); } if( TrPtr->success && ( prefs->resize || prefs->shear || prefs->horizontal || prefs->vertical || prefs->radial || prefs->cutFrame) ) // Displacement Xform requested { // First check whether recent luminance or fourier filtering if( prefs->luminance || prefs->fourier ) TrPtr->src = &im; TrPtr->dest = dest; // Set destination image parameters // most Xforms: dest = src destwidth = TrPtr->src->width; destheight = TrPtr->src->height; if( prefs->cutFrame ) { if( getFrame( TrPtr->src, &xoff, &yoff, prefs->fwidth, prefs->fheight, TrPtr->mode & _show_progress ) != 0 ) { TrPtr->success = 0; return; } //PrintError("x= %d, y= %d", xoff, yoff); destwidth = prefs->fwidth ; destheight = prefs->fheight ; } if(prefs->resize) { if( prefs->width == 0 && prefs->height == 0 ) { TrPtr->success = 0; PrintError( "Zero Destination Image Size" ); return; } if( prefs->width ) destwidth = prefs->width; else destwidth = (int)((double)TrPtr->src->width * (double)prefs->height / (double)TrPtr->src->height); if( prefs->height) destheight = prefs->height; else destheight = (int)((double)TrPtr->src->height * (double)prefs->width / (double)TrPtr->src->width); } if( destwidth <= 0 || destheight <= 0 ) { TrPtr->success = 0; PrintError( "Zero Destination Image Size" ); return; } // Allocate memory for destination image if( SetDestImage(TrPtr, destwidth, destheight) != 0 ) { TrPtr->success = 0; PrintError( "Not enough Memory."); goto _correct_exit; } // Check to see if the colors have the same or different displacement paras if( isColorSpecific( prefs ) ) // Color dependent { if( haveSameColorParas( prefs,0,1)) // R==G?? { fprintf(stderr, "PT correct "PROGRESS_VERSION" R==G\n" ); if( ! hasUsefulColorParas(prefs,0)) { fprintf(stderr, "Red/Green do NOTHING! Copying image data...\n" ); CopyImageData( TrPtr->dest, TrPtr->src ); fprintf(stderr, "Displacing just the Blue...\n" ); kstart=3; kend =3; } else if( ! hasUsefulColorParas(prefs,2)) { fprintf(stderr, "Blue does NOTHING! Copying image data...\n" ); CopyImageData( TrPtr->dest, TrPtr->src ); fprintf(stderr, "Displacing the Red/Green simultaneously...\n" ); kstart=4; kend =4; } else { kstart=4; kend =3; } } else if( haveSameColorParas( prefs,1,2)) // G==B?? { fprintf(stderr, "PT correct "PROGRESS_VERSION" G==B\n" ); if( ! hasUsefulColorParas(prefs,1)) { fprintf(stderr, "Green/Blue do NOTHING! Copying image data...\n" ); CopyImageData( TrPtr->dest, TrPtr->src ); fprintf(stderr, "Displacing just the Red...\n" ); kstart=1; kend =1; } else if( ! hasUsefulColorParas(prefs,0)) { fprintf(stderr, "Red does NOTHING! Copying image data...\n" ); CopyImageData( TrPtr->dest, TrPtr->src ); fprintf(stderr, "Displacing the Green/Blue simultaneously...\n" ); kstart=6; kend =6; } else { kstart=6; kend =1; } } else if( haveSameColorParas( prefs,2,0)) // R==B?? { fprintf(stderr, "PT correct "PROGRESS_VERSION" R==B\n" ); if( ! hasUsefulColorParas(prefs,0)) { fprintf(stderr, "Red/Blue do NOTHING! Copying image data...\n" ); CopyImageData( TrPtr->dest, TrPtr->src ); fprintf(stderr, "Displacing just the Green...\n" ); kstart=2; kend =2; } else if( ! hasUsefulColorParas(prefs,1)) { fprintf(stderr, "Green does NOTHING! Copying image data...\n" ); CopyImageData( TrPtr->dest, TrPtr->src ); fprintf(stderr, "Displacing the Red/Blue simultaneously...\n" ); kstart=5; kend =5; } else { kstart=5; kend =2; } } else { fprintf(stderr, "PT correct "PROGRESS_VERSION" R!=G!=B\n" ); if( ! hasUsefulColorParas(prefs,0)) { fprintf(stderr, "Red does NOTHING! Copying image data...\n" ); CopyImageData( TrPtr->dest, TrPtr->src ); fprintf(stderr, "Displacing the Green then Blue separately...\n" ); kstart=2; kend =3; } else if( ! hasUsefulColorParas(prefs,1)) { fprintf(stderr, "Green does NOTHING! Copying image data...\n" ); CopyImageData( TrPtr->dest, TrPtr->src ); fprintf(stderr, "Displacing the Blue then Red separately...\n" ); kstart=3; kend =1; } else if( ! hasUsefulColorParas(prefs,2)) { fprintf(stderr, "Blue does NOTHING! Copying image data...\n" ); CopyImageData( TrPtr->dest, TrPtr->src ); fprintf(stderr, "Displacing the Red then Green separately...\n" ); kstart=1; kend =2; } else { kstart = 1; kend = 3; } } } else // Color independent { fprintf(stderr, "PT correct "PROGRESS_VERSION" R==G==B\n" ); if( ! hasUsefulColorParas(prefs,0)) { fprintf(stderr, "Red,Green,Blue do NOTHING! But you asked for it...\n" ); } kstart = 0; kend = 0; } // Do the necessary displacements, either per color, 2-colors, or on all 3 colors. kdone=0; k=kstart; while(!kdone) { switch(k) // choose which color's paras to use { case 0: // RGB color = 0;// Use the Red paras break; case 1: // [0] = R case 2: // [1] = G case 3: // [2] = B color = k-1; break; case 4:// RG color=0; break; case 5:// RB color=0; break; case 6:// GB color=1; break; default: color=0; break; } i = 0; if( prefs->resize ) { if(prefs->cutFrame) { if( prefs->width ) scale_params[0] = ((double)prefs->fwidth)/ prefs->width; else scale_params[0] = ((double)prefs->fheight)/ prefs->height; if( prefs->height ) scale_params[1] = ((double)prefs->fheight)/ prefs->height; else scale_params[1] = scale_params[0]; } else { if( prefs->width ) scale_params[0] = ((double)TrPtr->src->width)/ prefs->width; else scale_params[0] = ((double)TrPtr->src->height)/ prefs->height; if( prefs->height ) scale_params[1] = ((double)TrPtr->src->height)/ prefs->height; else scale_params[1] = scale_params[0]; } SetDesc(stack[i],resize,scale_params); i++; } // JMW 2008/01/03 make the order the same as Adjust doing correct if( prefs->radial ) { switch( prefs->correction_mode) { case correction_mode_radial: SetDesc(stack[i],radial, radial_params); i++; radial_params[4] = ( (double)( TrPtr->src->width < TrPtr->src->height ? TrPtr->src->width : TrPtr->src->height) ) / 2.0; break; case correction_mode_vertical: SetDesc(stack[i],vertical, radial_params); i++; radial_params[4] = ((double)TrPtr->src->height) / 2.0; break; case correction_mode_deregister: SetDesc(stack[i],deregister, radial_params); i++; radial_params[4] = ((double)TrPtr->src->height) / 2.0; break; } for(j=0; j<4; j++) radial_params[j] = prefs->radial_params[color][j]; radial_params[5] = prefs->radial_params[color][4]; } if (prefs->vertical) { SetDesc(stack[i],vert,&(prefs->vertical_params[color])); i++; } if (prefs->horizontal) { SetDesc(stack[i],horiz,&(prefs->horizontal_params[color]) ); i++; } if( prefs->shear ) { shear_params[0] = prefs->shear_x / TrPtr->src->height; shear_params[1] = prefs->shear_y / TrPtr->src->width; SetDesc(stack[i],shear,shear_params); i++; } if( prefs->cutFrame ) { if( xoff != 0 ) { xdoff = (double) xoff + 0.5 * ( prefs->fwidth - TrPtr->src->width ) ; SetDesc(stack[i],horiz, &xdoff ); i++; } if( yoff != 0 ) { ydoff = (double)yoff + 0.5 * ( prefs->fheight - TrPtr->src->height) ; SetDesc(stack[i],vert,&ydoff); i++; } } stack[i].func = (trfn)NULL; if( !prefs->resize && !prefs->shear && !prefs->horizontal && !prefs->vertical && !prefs->radial && prefs->cutFrame ) // Only cutframe { ShiftImage(TrPtr, xoff, yoff); } else if( TrPtr->success != 0 && i != 0 ) { // Copy and reverse the stack to make the inverse stack int ii = 0; while(i) { stackinv[ii] = stack[i-1]; i--; ii++; } stackinv[ii].func = (trfn)NULL; fD.func = execute_stack_new; fD.param = stack; fDinv.func = execute_stack_new; fDinv.param = stackinv; transFormEx( TrPtr, &fD, &fDinv, k, 1 ); i = ii; } switch(k) // We use k as control var for a little statemachine: { case 0:// RGB kdone=1; break; case 1:// R case 2:// G case 3:// B if(k==kend) { kdone=1; } else { k++; if(k==4) k=1; } break; case 4:// RG case 5:// RB case 6:// GB if(k==kend) { kdone=1; } else { k=kend; } break; default: kdone=1; break; } }// END:while(!kdone) } if( !prefs->luminance && !prefs->fourier && !prefs->cutFrame && i == 0 ) // We did nothing! { TrPtr->success = 0; } if( TrPtr->success == 0 && ! (TrPtr->mode & _destSupplied)) myfree( (void**)TrPtr->dest->data ); _correct_exit: TrPtr->src = src; TrPtr->dest = dest; if( im.data != NULL ) myfree((void**)im.data); }