ADMDolbyContext::~ADMDolbyContext()
{
     for(int j=0;j<4;j++)
     {
         float *l=xv_left[j];
         float *r=xv_right[j];
         ADM_dezalloc(l);
         ADM_dezalloc(r);
     }
    
}
Exemple #2
0
/**
 * 	\fn gather
 * 	\brief Collect info from dialog and fill the param struct with it
 */
void  Ui_vobsubWindow::gather(void)
{
    if(param->subname) ADM_dezalloc(param->subname);
    param->subname=NULL;
    param->subname=ADM_strdup(ui.lineEditIdx->text().toAscii().data());
    param->index=ui.comboBoxLanguage->currentIndex();
}
/**
		\fn 	cleanupSub
		\brief 	Free all ressources allocated to source
*/
void cleanupSub(ADM_OCR_SOURCE *p)
{
  if(p->TsFile)
  {
	  	ADM_dezalloc(p->TsFile);
	  	p->TsFile=NULL;
  }
  if(p->subparam)
  {
	  vobSubParam *subparam=p->subparam;
	  if(subparam->subname)
	  {
		  ADM_dezalloc(subparam->subname);
		  subparam->subname=NULL;
	  }
	  
  }
  
}
void operator delete[] (void *c)
{
	ADM_dezalloc(c);
}
Exemple #5
0
int startAvidemux(int argc, char *argv[])
{
    printf("*************************\n");
    printf("  Avidemux v"ADM_VERSION);

#if defined( ADM_SUBVERSION )
#define MKSTRING(x) x
         printf(" (%s) .", MKSTRING(ADM_SUBVERSION)); 
#endif

    printf("\n*************************\n");
    printf(" http://www.avidemux.org\n");
    printf(" Code      : Mean, JSC, Grant Pedersen\n");
    printf(" GFX       : Nestor Di, [email protected]\n");
    printf(" Design    : Jakub Misak\n");
    printf(" FreeBSD   : Anish Mistry, [email protected]\n");
    printf(" Audio     : Mihail Zenkov\n");
    printf(" Mac OS X  : Kuisathaverat, Harry van der Wolf\n");
    printf(" Win32     : Grant Pedersen\n\n");

#ifdef __GNUC__
	printf("Compiler: GCC %s\n", __VERSION__);
#endif

	printf("Build Target: ");

#if defined(_WIN32)
	printf("Microsoft Windows");
#elif defined(__APPLE__)
	printf("Apple");
#else
	printf("Linux");
#endif

#if defined(ADM_CPU_X86_32)
	printf(" (x86)");
#elif defined(ADM_CPU_X86_64)
	printf(" (x86-64)");
#endif

	char uiDesc[15];
	getUIDescription(uiDesc);
	printf("\nUser Interface: %s\n", uiDesc);

#ifdef _WIN32
	char version[250];

	if (getWindowsVersion(version))
		printf("Operating System: %s\n", version);
#endif

#if defined(__USE_LARGEFILE) && defined(__USE_LARGEFILE64)
	printf("\nLarge file available: %d offset\n", __USE_FILE_OFFSET64);
#endif

    printf("Time: %s\n", ADM_epochToString(ADM_getSecondsSinceEpoch()));

	for(int i = 0; i < argc; i++)
	{
		printf("%d: %s\n", i, argv[i]);
	}

#ifndef __APPLE__
    ADM_InitMemcpy();
#endif
	printf("\nInitialising prefs\n");
	initPrefs();
	if(false==prefs->load()) // no prefs, set some sane default
    {
        setPrefsDefault();
    }
    CpuCaps::init();
    atexit(onexit);

#ifdef _WIN32
    win32_netInit();
#endif

    video_body = new ADM_Composer;

    UI_Init(argc, argv);
    AUDMEncoder_initDither();

    // Hook our UI...
    InitFactory();
    InitCoreToolkit();
    initFileSelector();

	// Load .avidemuxrc
    quotaInit();

    ADM_lavFormatInit();
	//***************Plugins *********************
	// Load system wide audio decoder plugin
#ifdef __APPLE__
    const char *startDir="../lib";
#else
    const char *startDir=ADM_RELATIVE_LIB_DIR;
#endif
    char *adPlugins = ADM_getInstallRelativePath(startDir, ADM_PLUGIN_DIR, "audioDecoder");
    char *avPlugins = ADM_getInstallRelativePath(startDir, ADM_PLUGIN_DIR, "audioDevices");
    char *aePlugins = ADM_getInstallRelativePath(startDir, ADM_PLUGIN_DIR, "audioEncoders");
    char *dmPlugins = ADM_getInstallRelativePath(startDir, ADM_PLUGIN_DIR, "demuxers");
    char *mxPlugins = ADM_getInstallRelativePath(startDir, ADM_PLUGIN_DIR, "muxers");
    char *vePlugins = ADM_getInstallRelativePath(startDir, ADM_PLUGIN_DIR, "videoEncoders");
    char *vdPlugins = ADM_getInstallRelativePath(startDir, ADM_PLUGIN_DIR, "videoDecoders");
    char *vfPlugins = ADM_getInstallRelativePath(startDir, ADM_PLUGIN_DIR, "videoFilters");
    char *sePlugins = ADM_getInstallRelativePath(startDir, ADM_PLUGIN_DIR, "scriptEngines");

    //***************Plugins *********************

	if(!initGUI(initialiseScriptEngines(sePlugins, video_body,getUISpecifSubfolder())))
	{
		printf("\n Fatal : could not init GUI\n");
		exit(-1);
	}

    delete [] sePlugins;

#if defined( USE_VDPAU)
  #if (ADM_UI_TYPE_BUILD!=ADM_UI_CLI)
    printf("Probing for VDPAU...\n");
    if(vdpauProbe()==true) printf("VDPAU available\n");
        else printf("VDPAU not available\n");
  #else
    printf("Cannot use VDPAU in cli mode %d,%d\n",ADM_UI_TYPE_BUILD,ADM_UI_CLI);
  #endif
#endif

#if defined( USE_XVBA)
  #if (ADM_UI_TYPE_BUILD!=ADM_UI_CLI)
    printf("Probing for XVBA...\n");
    if(xvbaProbe()==true) printf("XVBA available\n");
        else printf("XVBA not available\n");
  #else
    printf("Cannot use XVBA in cli mode %d,%d\n",ADM_UI_TYPE_BUILD,ADM_UI_CLI);
  #endif
#endif

#if defined( USE_LIBVA)
  #if (ADM_UI_TYPE_BUILD!=ADM_UI_CLI)
    printf("Probing for LIBVA...\n");
    if(libvaProbe()==true) printf("LIBVA available\n");
        else printf("LIBVA not available\n");
  #else
    printf("Cannot use LIBVA in cli mode %d,%d\n",ADM_UI_TYPE_BUILD,ADM_UI_CLI);
  #endif
#endif    

#ifdef USE_SDL
    char *drv=NULL;
    printf("Probing for SDL...\n");
    std::string sdlDriver=std::string("dummy");
    if(prefs->get(FEATURES_SDLDRIVER,&drv))
    {
        if(drv)
        {
            if(strlen(drv))
            {
                sdlDriver=std::string(drv);
            }
            ADM_dezalloc(drv);
        }
    }
    printf("Calling initSDL with driver=%s\n",sdlDriver.c_str());
    initSdl(sdlDriver);
#endif        
    //
    
    ADM_mx_loadPlugins(mxPlugins);
    delete [] mxPlugins;

    ADM_ad_loadPlugins(adPlugins);
    delete [] adPlugins;

    ADM_av_loadPlugins(avPlugins);
    delete [] avPlugins;

    ADM_ae_loadPlugins(aePlugins);
    delete [] aePlugins;

    ADM_dm_loadPlugins(dmPlugins);
    delete [] dmPlugins;

    ADM_ve6_loadPlugins(vePlugins,getUISpecifSubfolder());
    delete [] vePlugins;

    ADM_vf_loadPlugins(vfPlugins,getUISpecifSubfolder());
    delete [] vfPlugins;

    ADM_vd6_loadPlugins(vdPlugins);
    delete [] vdPlugins;


    // load local audio decoder plugins
    adPlugins=ADM_getHomeRelativePath("plugins6","audioDecoder");
    ADM_ad_loadPlugins(adPlugins);
    delete [] adPlugins;

    // load local video filter plugins
    vfPlugins=ADM_getHomeRelativePath("plugins6","videoFilter");
    ADM_vf_loadPlugins(vfPlugins,getUISpecifSubfolder());
    delete [] vfPlugins;


	

    ADM_lavInit();
    AVDM_audioInit();

    

    UI_RunApp();
    cleanUp();

    printf("Normal exit\n");
    return 0;
}
/**
          \fn GUI_FileSelWrite (const char *label, char **name, uint32_t access)
          \brief Ask for a file for reading (access=0) or writing (access=1)
        */
static	void GUI_FileSelSelectWriteInternal(const char *label, const char *ext, char **name)
{
    *name = NULL;
    QString str ;
    QString fileName,dot=QString(".");
    QString filterFile=QString(QT_TRANSLATE_NOOP("qfile","All files (*.*)"));
    bool doFilter = !!(ext && strlen(ext));
    QFileDialog::Options opts;
    int extSize=1;

    if(doFilter)
    {
        extSize+=strlen(ext);
    }
    //printf("Do filer=%d\n",(int)doFilter);
    std::string lastFolder;
    admCoreUtils::getLastWriteFolder(lastFolder);
    if (lastFolder.size())
    {
        QString outputPath = QFileInfo(QString::fromUtf8(lastFolder.c_str())).path();

        char *tmpinputname = NULL;
        QString inputBaseName = QString("");
        std::string lastRead;
        admCoreUtils::getLastReadFolder(lastRead);
        if (lastRead.size())
        {
            inputBaseName = QFileInfo(QString::fromUtf8(lastRead.c_str())).completeBaseName();
        }

        QString outputExt = QString("");
        if (doFilter)
        {
            outputExt = dot+QString(ext);
        }
        QString separator = QString("/");
        str = outputPath+separator+inputBaseName+outputExt;

        /* LASTDIR may have gone; then do nothing and use current dir instead (implied) */
        if (!QDir(outputPath).exists())
            str.clear();
    }

    if(doFilter)
    {
        filterFile=QString(ext)+QString(QT_TRANSLATE_NOOP("qfile"," files (*."))+QString(ext)+QString(");;")+filterFile;
    }
    fileName = QFileDialog::getSaveFileName(NULL,
                                            label,  // caption
                                            str,    // folder
                                            filterFile,   // filter
                                            NULL,QFileDialog::DontConfirmOverwrite);   // selected filter


    if (fileName.isNull() ) return;

    *name=(char *)ADM_alloc(  strlen(fileName.toUtf8().constData())+extSize);
    strcpy(*name,fileName.toUtf8().constData());

    // Check if we need to add an extension....
    if(doFilter)
    {
        if(!strstr(*name,"."))
        {
            strcat(*name,".");
            strcat(*name,ext);

            fileName=fileName+QString(".")+QString(ext);
        }
    }
    QFile newFile(fileName);
    if(newFile.exists())
    {
        QFileInfo fileInfo(newFile);
        QString q=QString(QT_TRANSLATE_NOOP("qfile","Overwrite file "))+fileInfo.fileName()+QString("?");
        if(!GUI_Question(q.toUtf8().constData()))
        {
            ADM_dezalloc(*name);
            *name=NULL;
            return;
        }
    }
    admCoreUtils::setLastWriteFolder( std::string(fileName.toUtf8().constData()));
}
/**
    \fn DIA_glyphEdit
    \brief Dialog to edit glyph
*/
uint8_t DIA_glyphEdit(void)
{
  char *glyphName;
  admGlyph head(1,1);
  
  
  uint32_t nbGlyph=0;
  uint8_t ret=0;
  // First select a file
  
   GUI_FileSelRead(QT_TR_NOOP("Select GlyphFile to edit"), &glyphName);
  if(!glyphName) return 0;
  
  // Try to load it
  if(!loadGlyph(glyphName,&head,&nbGlyph) || !nbGlyph)
  {
    destroyGlyphTree(&head);
    return 0;
  }
  // Convert the linear glyph to glyph array
  admGlyph *glyphArray[nbGlyph];
  admGlyph *cur=head.next;
  uint32_t idx=0;
  while(cur)
  {
     glyphArray[idx++]=cur;
     cur=cur->next;
  }
  ADM_assert(idx<=nbGlyph);
  nbGlyph=idx;
  // Glyph loaded, here we go
  currentGlyph=head.next;
  dialog=create_dialog1 ();
  gtk_register_dialog(dialog);
  
  // Register callbacks
#define ASSOCIATE(x,y)   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(x),y)
#define CONNECT(x,y,z) 	gtk_signal_connect(GTK_OBJECT(WID(x)), #y,GTK_SIGNAL_FUNC(z),   NULL);
#define ACTION_PREV 10
#define ACTION_NEXT 20
#define ACTION_PREV_EMPTY 30
#define ACTION_NEXT_EMPTY 40
#define ACTION_SAVE 50
#define ACTION_DELETE 60
#define ACTION_ACTIVATE 70
#define ACTION_SEARCH 80
#define ACTION_REWIND 90
  
  ASSOCIATE(buttonPrev,ACTION_PREV);
  ASSOCIATE(buttonNext,ACTION_NEXT);
  ASSOCIATE(buttonEmptyPrev,ACTION_PREV_EMPTY);
  ASSOCIATE(buttonNextEmpty,ACTION_NEXT_EMPTY);
  ASSOCIATE(buttonSave,ACTION_SAVE);
  ASSOCIATE(buttonDelete,ACTION_DELETE);
  ASSOCIATE(buttonSearch,ACTION_SEARCH);
  ASSOCIATE(buttonRewind,ACTION_REWIND);
  
  
  CONNECT(drawingarea1,expose_event,glyphDraw);
  CONNECT(entry1,activate,glyphActivate);
  
  gtk_widget_show(dialog);
  glyphUpdate();
  while(1)
  {
   gint b=gtk_dialog_run(GTK_DIALOG(dialog));
    switch(b)
    {
      case ACTION_REWIND:
                            currentGlyph=head.next;
                            glyphUpdate();
                            continue;
      case ACTION_SEARCH:
                          {
                          char *tomatch=NULL;
                          {
                            // Dialog Factory to the rescue ! 
                              
                              diaElemText txt(&tomatch,QT_TR_NOOP("String"),NULL);
                              diaElem *elems[]={&txt};
                              if(!diaFactoryRun(QT_TR_NOOP("Search string"),1,elems))
                              {
                                  continue;
                                  break;
                              }
                          }
                          printf("Searched string <%s>\n",tomatch);
                          
                          while(currentGlyph->next)
                          {
                             currentGlyph=currentGlyph->next;
                             glyphUpdate();
                             
                             if(currentGlyph->code)
                             {
                                printf("%s vs %s\n",currentGlyph->code,tomatch);
                                if(!strcmp(currentGlyph->code,tomatch))
                                {
                                  
                                  glyphUpdate();
                                  break;  
                                }
                             }
                          }
                          ADM_dezalloc(tomatch);
                          if(!currentGlyph->next)
                                GUI_Error_HIG(QT_TR_NOOP("End reached"),QT_TR_NOOP("No more glyphs"));
                          }
                          
                          continue;
                          break;
                        ;
      case ACTION_PREV: 
                        printf("PREV\n");
                        if(currentGlyph!=head.next)
                        {
                           admGlyph *father;
                           father=glyphSearchFather(currentGlyph,&head);
                           if(father)
                           {
                               currentGlyph=father;
                               glyphUpdate();
                           }
                          
                        }
                        continue;break;
      case ACTION_NEXT: 
                        printf("NEXT\n");
                        if(currentGlyph->next)
                        {
                          currentGlyph=currentGlyph->next; 
                          glyphUpdate();
                        }
                        continue;break; 
      case ACTION_NEXT_EMPTY: 
                        printf("NEXT EMPTY\n");
                        while(1)
                        {
                            if(currentGlyph->next)
                            {
                              currentGlyph=currentGlyph->next; 
                              glyphUpdate();
                              if(!currentGlyph->code || !*(currentGlyph->code))
                              {
                                break;
                              }
                            }
                            else 
                            {
                              GUI_Error_HIG(QT_TR_NOOP("End reached"),QT_TR_NOOP("No more glyphs"));
                              break;
                            }
                        }
                        continue;break; 
        case ACTION_PREV_EMPTY: 
                        printf("PREV EMPTY\n");
                        while(1)
                        {
                            if(currentGlyph!=head.next)
                            {
                              admGlyph *father;
                              father=glyphSearchFather(currentGlyph,&head);
                              if(father)
                              {
                                  currentGlyph=father;
                                  glyphUpdate();
                                   if(!currentGlyph->code || !*(currentGlyph->code))
                                    {
                                      break;
                                    }
                                  continue;
                              } 
                            } 
                            GUI_Error_HIG(QT_TR_NOOP("Head reached"),QT_TR_NOOP("No more glyphs"));
                            break;
                        }
                        continue;break;
      case ACTION_SAVE:
                    saveGlyph(glyphName,&head,nbGlyph);
                    continue;break;
      case ACTION_DELETE:
                  {
                      admGlyph *father;
                      father=glyphSearchFather(currentGlyph,&head);
                      ADM_assert(father);
                      father->next=currentGlyph->next;
                      delete currentGlyph;
                      
                      currentGlyph=father;
                        if(father==&head && head.next)
                          currentGlyph=head.next;
                      nbGlyph--;
                      glyphUpdate();
                      continue;break; 
                  }
      case ACTION_ACTIVATE:
                  {
                      const gchar  *old;
                      if(currentGlyph->code) delete [] currentGlyph->code;
                      currentGlyph->code=NULL;
                      // Retrieve new one
                      old=gtk_entry_get_text (GTK_ENTRY (WID(entry1)));
                      
                      if(old && strlen(old))
                      {
                        currentGlyph->code=new char[strlen(old)+1];
                        strcpy(currentGlyph->code,old);
                      }
                    
                  }
                        continue;break; 
    }
    break; // exit while(1)
  }
  
  gtk_unregister_dialog(dialog);
  gtk_widget_destroy(dialog);
  
  destroyGlyphTree(&head);
  return ret;

}
/**
    \fn DIA_ocrGen
    \brief Dialog to select input & output files before calling the actual ocr engine
*/
uint8_t DIA_ocrGen(void)
{

  vobSubParam subparam={NULL,0,0};
  char *srtFileName=NULL;
  char *glyphFileName=NULL;
  admGlyph head(16,16);
  char *globalGlyph=NULL;
  uint32_t globalGlyphOn=0;
  ADM_OCR_SOURCE source;
  
  memset(&source,0,sizeof(source));
  
  source.type=ADM_OCR_TYPE_VOBSUB;
  source.subparam=&subparam;
  
  prefs->get(FEATURE_GLOBAL_GLYPH_ACTIVE,&globalGlyphOn);
  if(globalGlyphOn)
  {
     prefs->get(FEATURE_GLOBAL_GLYPH_NAME,&globalGlyph);
     if(!*globalGlyph)
     {
        ADM_dezalloc(globalGlyph);
        globalGlyph=NULL; 
     }
  }

  if(globalGlyph)
  {
    glyphFileName=globalGlyph;
  }
_again:  
  // Fist build a dialogFactory to get input and output files
  diaElemButton   selectIdx(QT_TR_NOOP("Select idx file:"), cb_idx,&subparam,NULL);
  diaElemFile     selectGlyph(1,&glyphFileName,QT_TR_NOOP("Use GlyphSet (optional):"), NULL, QT_TR_NOOP("Select GlyphSet file"));
  diaElemFile     selectSrt(1,&srtFileName,QT_TR_NOOP("Output SRT file"), NULL, QT_TR_NOOP("Save SRT file"));
  
  diaElem *elems[]={&selectIdx,&selectSrt,&selectGlyph};
  
   uint32_t n=3;
   if(globalGlyph)
   {
     n--; // Remove glyph from dialog
   }
  
    if(!diaFactoryRun(QT_TR_NOOP("Select input and ouput files"),n,elems))
        {
          cleanupSub(&source);
          if(srtFileName )ADM_dezalloc(srtFileName);
          srtFileName=NULL;
          destroyGlyphTree(&head);
          return 0;
        }
        if(!ADM_fileExist(subparam.subname))
        {
          GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("The idx/sub file does not exist."));
          goto _again; 
        }
        if(!srtFileName || !*srtFileName)
        {
          GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Please Select a valid output SRT file."));
          goto _again; 
        }
         if(glyphFileName && *glyphFileName)
         {
           if(!ADM_fileExist(glyphFileName))
            {
              GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("The idx/sub file does not exist."));
              goto _again; 
            }
            // Purge previous glyph set if any
            destroyGlyphTree(&head);
            uint32_t nb;
            printf("[OCR] Loading glyphset :<%s>\n",glyphFileName);
            if(!loadGlyph(glyphFileName,&head,&nb))
            {
              GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Cannot load the glyphset file."));
              goto _again;               
            }
            printf("[GLYPH] Found %u glyph\n");
         }
        // We have our SRT and our idx/sub files : Go go go
         
    if(ADM_ocr_engine(source,srtFileName,&head))
    {
        // Save glyph set 
        if(globalGlyph)
        {
          uint32_t nb=1;
           saveGlyph(globalGlyph,&head,nb);
        }
        else
        {
            char *save=NULL;
            uint32_t nb=1;
              diaElemFile     selectSave(1,&save,QT_TR_NOOP("GlyphSet filename"), NULL, QT_TR_NOOP("Save GlyphSet file"));
              diaElem *elems2[]={&selectSave};
            if(diaFactoryRun(QT_TR_NOOP("Save Glyph"),1,elems2))
            {
              saveGlyph(save,&head,nb);
            }
            if(save) ADM_dezalloc(save);
        }
    }

  cleanupSub(&source);
  if(srtFileName )ADM_dezalloc(srtFileName);
  srtFileName=NULL;
  destroyGlyphTree(&head);
  return 1;  
}
/**
    \fn DIA_ocrDvb
    \brief Dialog to select input & output files before calling the actual ocr engine
*/
uint8_t DIA_ocrDvb(void)
{

  vobSubParam subparam={NULL,0,0};
  char *srtFileName=NULL;
  char *glyphFileName=NULL;
  char *tsFileName=NULL;
  admGlyph head(16,16);
  char *globalGlyph=NULL;
  uint32_t globalGlyphOn=0;
  uint32_t pid=0x96;
  ADM_OCR_SOURCE source;
  
  memset(&source,0,sizeof(source));
  source.type=ADM_OCR_TYPE_TS;
  
  prefs->get(FEATURE_GLOBAL_GLYPH_ACTIVE,&globalGlyphOn);
  if(globalGlyphOn)
  {
     prefs->get(FEATURE_GLOBAL_GLYPH_NAME,&globalGlyph);
     if(!*globalGlyph)
     {
        ADM_dezalloc(globalGlyph);
        globalGlyph=NULL; 
     }
  }

  if(globalGlyph)
  {
    glyphFileName=globalGlyph;
  }
_againX:  
  // Fist build a dialogFactory to get input and output files
  diaElemFile     selectTs(1,&tsFileName,QT_TR_NOOP("Input TS:"), NULL, QT_TR_NOOP("Select TS file"));
  diaElemUInteger selectPid(&pid,QT_TR_NOOP("Subtitle PID:"),0,255);
  diaElemFile     selectGlyph(1,&glyphFileName,QT_TR_NOOP("Use glyphset (optional):"), NULL, QT_TR_NOOP("Select GlyphSet file"));  
  diaElemFile     selectSrt(1,&srtFileName,QT_TR_NOOP("Output SRT file"), NULL, QT_TR_NOOP("Save SRT file"));
  
  diaElem *elems[]={&selectTs,&selectPid,&selectSrt,&selectGlyph};
  
  
   uint32_t n=4;
   if(globalGlyph)
   {
     n--; // Remove glyph from dialog
   }
  
        if( !diaFactoryRun(QT_TR_NOOP("Select input and ouput files"),n,elems))
        {
          cleanupSub(&source);
          if(srtFileName )ADM_dezalloc(srtFileName);
          srtFileName=NULL;
          destroyGlyphTree(&head);
          return 0;
        }
        // TS file exists ?
        if(!ADM_fileExist(tsFileName))
        {
        	  GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Please Select a valid TS file."));
        	  goto _againX;
        }
       
        if(!srtFileName || !*srtFileName)
        {
          GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Please Select a valid output SRT file."));
          goto _againX; 
        }
         if(glyphFileName && *glyphFileName)
         {
           if(!ADM_fileExist(glyphFileName))
            {
              GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("The idx/sub file does not exist."));
              goto _againX; 
            }
            // Purge previous glyph set if any
            destroyGlyphTree(&head);
            uint32_t nb;
            printf("[OCR] Loading glyphset :<%s>\n",glyphFileName);
            if(!loadGlyph(glyphFileName,&head,&nb))
            {
              GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Cannot load the glyphset file."));
              goto _againX;               
            }
            printf("[GLYPH] Found %u glyph\n");
         }
        // We have our SRT and our TS file
        // Call the OCR engine...
         source.TsFile=ADM_strdup(tsFileName);
         source.TsPid=pid;
         ADM_ocr_engine(source,srtFileName,&head);
        
        // Save glyph set 

        if(globalGlyph)
        {
          uint32_t nb=1;
           saveGlyph(globalGlyph,&head,nb);
        }else
        {
            char *save=NULL;
            uint32_t nb=1;
              diaElemFile     selectSave(1,&save,QT_TR_NOOP("GlyphSet filename"), NULL, QT_TR_NOOP("Save GlyphSet file"));
              diaElem *elems2[]={&selectSave};
            if( diaFactoryRun(QT_TR_NOOP("Save GlyphSet"),1,elems2))
            {
              saveGlyph(save,&head,nb);
            }
            if(save) ADM_dezalloc(save);
        }

  cleanupSub(&source);
  if(srtFileName )ADM_dezalloc(srtFileName);
  srtFileName=NULL;
  
  if(tsFileName )ADM_dezalloc(tsFileName);
  tsFileName=NULL;
  
  destroyGlyphTree(&head);
  return 1;  
}