EDGE.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 2.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 - 2007 OpenFX Development Team
00004 
00005 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019 You may contact the OpenFX development team via elecronic mail
00020 at core@openfx.org, or visit our website at http://openfx.org for
00021 further information and support details.
00022 -- */
00023 
00024 /* EDGE.C  */
00025 
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <float.h>
00029 #include <math.h>
00030 #include <windows.h>
00031 #include "struct.h"           /* general structures    */
00032 #include "..\common\postprocess\ximage.h"
00033 #include "local.h"
00034 
00035 #include "edge.h"
00036 
00037 #if __X__MIPS__
00038 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00039 #endif
00040 
00041 static HINSTANCE hDLLinstance=NULL; /* use to pick up resources from DLL  */
00042 
00043 #include "utils.h"
00044 #include "paint.c"
00045 
00046 
00047 #if __WATCOMC__
00048 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00049 #elif __BC__
00050 BOOL WINAPI DllEntryPoint(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00051 #else
00052 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00053 #endif
00054   switch (dwReason) {
00055     case DLL_PROCESS_ATTACH:
00056 #if __X__MIPS__
00057       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00058 #endif
00059       hDLLinstance = hDLL;  /* handle to DLL file */
00060       break;
00061     case DLL_PROCESS_DETACH:
00062 #if __X__MIPS__
00063       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00064 #endif
00065       break;
00066   }
00067 return (int)TRUE;
00068 }
00069 
00070 #if __SC__
00071 #pragma startaddress(DllMain)
00072 #endif
00073 
00074 static void ConvertToGray(long Xres, long Yres,
00075                           fullscreenbuffer *S){
00076 
00077  unsigned char g;
00078  long i,j;
00079  for(i=0;i<Yres;i++){
00080    for(j=0;j<Xres;j++){
00081      g=(unsigned char)(((long)S->R+(long)S->G+(long)S->B)/3);
00082      S->R=g; S->G=g; S->B=g;
00083      S++;
00084    }
00085  }
00086 }
00087 
00088 static void Convolve(long Xres, long Yres,
00089                      fullscreenbuffer *Si,
00090                      fullscreenbuffer *So,
00091                      double scale,
00092                      long bias,
00093                      long filterX, long filterY,
00094                      double *filter){
00095  fullscreenbuffer *S;
00096  long i,j,k,l,c,r;
00097  double ar,ag,ab,weight;
00098  r=filterY/2;
00099  c=filterX/2;
00100  for(i=r;i<Yres-r;i++){
00101    for(j=c;j<Xres-c;j++){
00102      ar=ag=ab=0.0;
00103      for(l=0;l<filterY;l++)for(k=0;k<filterX;k++){
00104        S=(Si+(Xres*(i+(l-r))+(j+(k-c))));
00105        weight = *(filter+filterX*l+k);
00106        ar+=(double)S->R*weight;
00107        ag+=(double)S->G*weight;
00108        ab+=(double)S->B*weight;
00109      }
00110      S=(So+(Xres*i)+j);
00111      S->R = (unsigned char)max(0.0,(min(255.0,bias+ar*scale)));
00112      S->G = (unsigned char)max(0.0,(min(255.0,bias+ag*scale)));
00113      S->B = (unsigned char)max(0.0,(min(255.0,bias+ab*scale)));
00114    }
00115  }
00116 }
00117 
00118 long _RenderImageProcess(char *PrmList, XIMAGE *lpXimage){
00119  long v,i,j,atype,Xres,Yres;
00120  long lA,lB,lC,lD,lE,lF,lG,lH,lI,MaxDif,threshold;
00121  long lineAEIbelow,lineAEIabove,lineAEIdif;
00122  long lineBEHbelow,lineBEHabove,lineBEHdif;
00123  long lineCEGbelow,lineCEGabove,lineCEGdif;
00124  long lineDEFbelow,lineDEFabove,lineDEFdif;
00125  char name_path[255];
00126  fullscreenbuffer *s,*S,*So,*Si;
00127  Xres=lpXimage->Xmax; Yres=lpXimage->Ymax;
00128  So=(fullscreenbuffer *)X__Malloc(Xres*Yres*(long)sizeof(fullscreenbuffer));
00129  if(So == NULL){
00130    MessageBox(GetFocus(),"Memory Out",NULL,MB_OK);
00131    return 0;
00132  }
00133  memcpy(So,lpXimage->Screen,sizeof(fullscreenbuffer)*Xres*Yres);
00134  sscanf(PrmList,"%s %ld",name_path,&v);
00135  threshold=16*3;
00136 // threshold=8*3;  // for mixing in edges with original image
00137  atype=6;
00138  if(atype == 1){
00139    memset(So,0,sizeof(fullscreenbuffer)*Xres*Yres);
00140    for(i=1;i<Yres-1;i++)for(j=1;j<Xres-1;j++){
00141      Si=(lpXimage->Screen+(Xres*(i-1))+(j-1));
00142      lA = (long)Si->R + (long)Si->G + (long)Si->B;
00143      Si=(lpXimage->Screen+(Xres*(i  ))+(j-1));
00144      lB = (long)Si->R + (long)Si->G + (long)Si->B;
00145      Si=(lpXimage->Screen+(Xres*(i+1))+(j-1));
00146      lC = (long)Si->R + (long)Si->G + (long)Si->B;
00147      Si=(lpXimage->Screen+(Xres*(i-1))+(j  ));
00148      lD = (long)Si->R + (long)Si->G + (long)Si->B;
00149      Si=(lpXimage->Screen+(Xres*(i  ))+(j  ));
00150      lE = (long)Si->R + (long)Si->G + (long)Si->B;
00151      Si=(lpXimage->Screen+(Xres*(i+1))+(j  ));
00152      lF = (long)Si->R + (long)Si->G + (long)Si->B;
00153      Si=(lpXimage->Screen+(Xres*(i-1))+(j+1));
00154      lG = (long)Si->R + (long)Si->G + (long)Si->B;
00155      Si=(lpXimage->Screen+(Xres*(i  ))+(j+1));
00156      lH = (long)Si->R + (long)Si->G + (long)Si->B;
00157      Si=(lpXimage->Screen+(Xres*(i+1))+(j+1));
00158      lI = (long)Si->R + (long)Si->G + (long)Si->B;
00159      lineAEIabove=(lB+lC+lF)/3;
00160      lineAEIbelow=(lD+lG+lH)/3;
00161      lineAEIdif=labs(lineAEIbelow-lineAEIabove);
00162      lineBEHabove=(lC+lF+lI)/3;
00163      lineBEHbelow=(lA+lD+lG)/3;
00164      lineBEHdif=labs(lineBEHbelow-lineBEHabove);
00165      lineCEGabove=(lA+lB+lD)/3;
00166      lineCEGbelow=(lH+lF+lI)/3;
00167      lineCEGdif=labs(lineCEGbelow-lineCEGabove);
00168      lineDEFabove=(lA+lB+lC)/3;
00169      lineDEFbelow=(lG+lH+lI)/3;
00170      lineDEFdif=labs(lineDEFbelow-lineDEFabove);
00171      MaxDif=max(lineAEIdif,lineBEHdif);
00172      MaxDif=max(lineCEGdif,MaxDif);
00173      MaxDif=max(lineDEFdif,MaxDif);
00174      S=(So+(Xres*i)+j);
00175      if(MaxDif > threshold){
00176        S->R = (unsigned char)(255.0);
00177        S->G = (unsigned char)(255.0);
00178        S->B = (unsigned char)(255.0);
00179      }
00180      /*  mixed in edges */
00181 //     S->R = (unsigned char)min(255.0,(double)S->R + 0.005*(double)MaxDif*(double)S->R);
00182 //     S->G = (unsigned char)min(255.0,(double)S->G + 0.005*(double)MaxDif*(double)S->G);
00183 //     S->B = (unsigned char)min(255.0,(double)S->B + 0.005*(double)MaxDif*(double)S->B);
00184    }
00185  }
00186  else if(atype == 3){
00187    /* blurring */
00188    double filter[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
00189    Convolve(Xres,Yres,lpXimage->Screen,So,1.0/25.0,0,5,5,filter);
00190  }
00191  else if(atype == 4){
00192    /* laplace edge enhancement */
00193    double filter[]={0.0,-1.0,0.0,  -1.0,4.0,-1.0,  0.0,-1.0,0.0};
00194    Convolve(Xres,Yres,lpXimage->Screen,So,1.0,128,3,3,filter);
00195  }
00196  else if(atype == 5){
00197    /* High-Pass Spatial HP3 */
00198    double filter[]={1.0,-2.0,1.0,  -2.0,5.0,-2.0,  1.0,-2.0,1.0};
00199    Convolve(Xres,Yres,lpXimage->Screen,So,1.0,128,3,3,filter);
00200  }
00201  else if(atype == 2){
00202    /* High-Pass Spatial HP2 */
00203    double filter[]={0.0,-1.0,0.0,  -1.0,5.0,-1.0,  0.0,-1.0,0.0};
00204    Convolve(Xres,Yres,lpXimage->Screen,So,1.0,128,3,3,filter);
00205  }
00206  else if(atype == 6){
00207    /* High-Pass Spatial HP1  for edge enhancement */
00208    double filter[]={-1.0,-1.0,-1.0,  -1.0,9.0,-1.0,  -1.0,-1.0,-1.0};
00209    Convolve(Xres,Yres,lpXimage->Screen,So,1.00,128,3,3,filter);
00210    /* mix in high frequency */
00211    for(i=1;i<Yres-1;i++)for(j=1;j<Xres-1;j++){
00212      S=(So+(Xres*i)+j);
00213      s=(lpXimage->Screen+(Xres*i)+j);
00214      S->R = (unsigned char)max(0.0,min(255.0,0.80*(double)s->R + 0.40*((double)S->R-128)));
00215      S->G = (unsigned char)max(0.0,min(255.0,0.80*(double)s->G + 0.40*((double)S->G-128)));
00216      S->B = (unsigned char)max(0.0,min(255.0,0.80*(double)s->B + 0.40*((double)S->B-128)));
00217    }
00218  }
00219  else if(atype == 7){
00220    /* Low pass Spatial LP1 */
00221    double filter[]={0.111111,0.111111,0.111111,
00222                     0.111111,0.111111,0.111111,
00223                     0.111111,0.111111,0.111111};
00224    Convolve(Xres,Yres,lpXimage->Screen,So,1.0,0,3,3,filter);
00225  }
00226 
00227  memcpy(lpXimage->Screen,So,sizeof(fullscreenbuffer)*Xres*Yres);
00228  X__Free(So);
00229  return 1;
00230 }
00231 
00232 /*************** Function that renders any of the OpenGL Functionality ************/
00233 
00234 long _RenderGLexternal(char *PrmList, XIMAGE *lpXimage){
00235 MessageBox(NULL,"OpenGL function called","OK",MB_OK);
00236  return 1;
00237 }
00238 /**********************************************************************************/
00239 
00240 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00241 
00242 static int  version=0;
00243 
00244 char * _SetExternalParameters(
00245   char *Op,                 /* string for the parameters                  */
00246   HWND hWnd,                /* parent window                              */
00247   long ruler,               /* ruler scale value to facilitate scaling    */
00248   char *name,               /* name of DLL file with the effect           */
00249   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00250                                     ){
00251  /* output name and buffer should be as long as necessary to hold full string */
00252  char buffer[256];
00253  if(Op != NULL){  /* parameters exist so read them off the list */
00254    sscanf(Op,"%s %ld",buffer,&version);
00255  }
00256  /*   Do the user interface as required to set up the effect, may use a     */
00257  /*   dialog box etc. Return old string if effect is cancelled (no change)  */
00258  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG_EDGE),hWnd,
00259               (DLGPROC)DlgProc) == FALSE)return Op;
00260  /* Free space occupied by old parameter string */
00261  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00262  /* print the parameters into the buffer */
00263  sprintf(buffer,"%s %ld",name,version);
00264  /* Prepare the output buffer to take copy of parameter list */
00265  if((Op=(char *)CALL_MALLOC(strlen(buffer)+1)) == NULL){
00266   MessageBox (GetFocus(),"External effect: Out of memory","Error",
00267                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00268    return NULL;
00269  }
00270  /* Copy the parameter string to the output buffer */
00271  strcpy(Op,buffer);
00272  return Op;
00273 }
00274 
00275 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00276  char str[32];
00277  BOOL err;
00278  switch( msg ) {
00279    case WM_INITDIALOG:
00280 #if 0
00281      SetDlgItemInt(hwnd,DLG_BLUR_SAMPLES,samples,FALSE);
00282      SetDlgItemInt(hwnd,DLG_BLUR_D1,id1,FALSE);
00283      if(back == 1)SendDlgItemMessage(hwnd,DLG_BLUR_BACK,BM_SETCHECK,TRUE,0);
00284      if     (atype == 1)
00285        SendDlgItemMessage(hwnd,DLG_BLUR_ACC1,BM_SETCHECK,TRUE,0);
00286      else if(atype == 2)
00287        SendDlgItemMessage(hwnd,DLG_BLUR_ACC2,BM_SETCHECK,TRUE,0);
00288      else
00289        SendDlgItemMessage(hwnd,DLG_BLUR_ACC3,BM_SETCHECK,TRUE,0);
00290 #endif
00291      CentreDialogOnScreen(hwnd);
00292      return TRUE;
00293    case WM_PAINT:
00294      PaintBackground(hwnd);
00295      break;
00296    case WM_COMMAND:
00297      switch(LOWORD(wparam)){
00298         case IDCANCEL:
00299           EndDialog(hwnd,FALSE);
00300           return(TRUE);
00301         case IDOK:
00302 #if 0
00303           samples=GetDlgItemInt(hwnd,DLG_BLUR_SAMPLES,&err,FALSE);
00304           id1=GetDlgItemInt(hwnd,DLG_BLUR_D1,&err,FALSE);
00305           if(samples < 0)samples=1;
00306           if(SendDlgItemMessage(hwnd,DLG_BLUR_BACK,BM_GETCHECK,0,0))
00307                back=1;
00308           else back=0;
00309           if   (SendDlgItemMessage(hwnd,DLG_BLUR_ACC3,BM_GETCHECK,0,0))
00310                atype=3;
00311           else if(SendDlgItemMessage(hwnd,DLG_BLUR_ACC2,BM_GETCHECK,0,0))
00312                atype=2;
00313           else atype=1;
00314 #endif
00315           EndDialog(hwnd,TRUE);
00316           return(TRUE);
00317         default:
00318           break;
00319       }
00320       break;
00321     default: break;
00322  }
00323  return FALSE;
00324 }
00325 

Generated on Sun Apr 27 14:20:12 2014 for OpenFX by  doxygen 1.5.6