Пример #1
0
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++
        Main
   +++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
uint8_t ADM_ocr_engine( void)
{
// 
    uint32_t nbSub=0;
    FILE *out=NULL;
    head.next=NULL;
    ADMVideoVobSub *vobsub=NULL;
    uint32_t startTime,endTime;
    uint32_t w,h,oldw=0,oldh=0;
    uint32_t oldbitmapw=0;
    uint32_t oldbitmaph=0;
    uint32_t first,last;
    uint32_t seqNum;
    char     text[1024];
    lang_index=0;
    nbGlyphs=0;
    ReplyType reply;
    
// Create UI && prepare callback
    
    dialog=DIA_ocr();
    gtk_register_dialog(dialog);
#define ASSOCIATE(x,y)   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(x),y)
    ASSOCIATE(buttonStart,actionGo);
    ASSOCIATE(buttonOk,   actionAccept);
    ASSOCIATE(buttonSkip,     actionSkip);
    ASSOCIATE(buttonSkipAll,     actionSkipAll);
    ASSOCIATE(buttonIgnore,   actionIgnore);
    ASSOCIATE(buttonCalibrate,   actionCalibrate);
    
    ASSOCIATE(buttonGlyphLoad,   actionLoadGlyph);
    ASSOCIATE(buttonGlyphSave,   actionSaveGlyph);
    
    ASSOCIATE(buttonVobsub,   actionLoadVob);
    ASSOCIATE(buttonSrt,   actionSaveSub);
   
    gtk_widget_show(dialog);
//  disable
    
    mainDisplay=WID(drawingareaBitmap);
    smallDisplay=WID(drawingareaSmall);
    
    CONNECT(drawingareaBitmap,expose_event,gui_draw);
    CONNECT(drawingareaSmall,expose_event,gui_draw_small);

    CONNECT(entry,activate,cb_accept);
_again:    
    reply=setup();
    if(reply==ReplyClose) goto endIt;
    
    printf("Go go go\n");
    
    // Everything ready go go go 
         
    redraw_x=redraw_y=0;
    GTK_PURGE;
//  Time to go
    // Inactivate frame1=glyph    frame2=in/out  buttonStart
    gtk_widget_set_sensitive(WID(buttonStart),0);
    gtk_widget_set_sensitive(WID(frameGlyph),0);
    gtk_widget_set_sensitive(WID(frameLoad),0);
    gtk_widget_set_sensitive(WID(frameBitmap),1);

    gtk_widget_set_sensitive(WID(buttonStart),0);
   
  
   char *fileout;
   fileout=(char *)gtk_label_get_text(GTK_LABEL(WID(labelSrt)));
   if(!fileout)
    {
      GUI_Error_HIG(_("Incorrect output file"), NULL);
        goto _again;
    }
    out=fopen(fileout,"wb");
    if(!out)
    {
      GUI_Error_HIG(_("Output file error"), _("Could not open \"%s\" for writing."), fileout);
        goto _again;
    }
     
    vobsub=new ADMVideoVobSub(subparam.subname,subparam.index);
    nbSub=vobsub->getNbImage();
   
    if(!nbSub)
    {
      GUI_Error_HIG(_("Problem loading sub"), NULL);
        delete vobsub;
        vobsub=NULL;
        goto _again;
     }
    seqNum=1;   // Sub number in srt file
    oldw=oldh=0;

    //******************    
    // Load all bitmaps
    //******************
    for(uint32_t i=0;i<nbSub;i++)
    {
            first=last=0;
            bitmap=vobsub->getBitmap(i,&startTime, &endTime,&first,&last);
            ADM_assert(last>=first);
            
            // something ?
            if(!bitmap) continue;
            if(first==last) continue;

            // If the bitmap size changed or does not exist yet...
            if(!workArea || oldbitmapw!=bitmap->_width || oldbitmaph!=bitmap->_height)
            {
              if(workArea) 
              {
                delete [] workArea;
                workArea=NULL; 
              }
              // Workarea is actually bigger than what we use
              workArea=new uint8_t[bitmap->_width*(bitmap->_height)];
              memset(workArea,0,bitmap->_width*(bitmap->_height));
            }
            oldbitmaph=bitmap->_height;
            oldbitmapw=bitmap->_width;
           // 
           w=bitmap->_width;
           h=last-first+1;
           redraw_x=w;
           redraw_y=h;
           //**
           
           // Build
againPlease:
           mergeBitmap(bitmap->_bitmap+first*w, workArea, bitmap->_alphaMask+first*w,  w,   h);
           if(oldw!=w || oldh !=h)
           {                
                GTK_PURGE;  // Force redaw
           }
           // Merge
             GTK_PURGE;
             gui_draw();
             GTK_PURGE; 
             // OCR
              reply=ocrBitmap(workArea,w,h);
              if(reply==ReplyClose) goto endIt;
              if(reply==ReplyCalibrate)
                {
                        //
                        //printf("TADA!!!!\n");
                        int val;
#if 0
                         val=minAlpha;
                        if(DIA_GetIntegerValue(&val, 3, 7, "Minimum alpha value", "Enter new minimum alpha"))
                        {
                                minAlpha=val;

                        }
#endif
                        val=minThreshold;
                        if(DIA_GetIntegerValue(&val, 0x30, 0x80, "Minimum pixel value", "Enter new minimum pixel"))
                        {
                                minThreshold=val;

                        }
                        goto againPlease;
                }
             
             //
             gtk_label_set_text(GTK_LABEL(WID(labelText)),decodedString);
             fprintf(out,"%d\n",seqNum++);
             uint16_t hh,mm,ss,ms;
             ms2time(startTime, &hh, &mm, &ss, &ms);
             fprintf(out,"%02d:%02d:%02d,%03d --> ",hh,mm,ss,ms);
             ms2time(endTime, &hh, &mm, &ss, &ms);
             fprintf(out,"%02d:%02d:%02d,%03d\n",hh,mm,ss,ms);
             fprintf(out,"%s\n\n",decodedString);
             //             
             oldw=w;
             oldh=h;
             // Update infos
             sprintf(text,"%03d/%03d",i+1,nbSub);
             gtk_label_set_text(GTK_LABEL(WID(labelNbLines)),text);
             sprintf(text,"%03d",nbGlyphs);
             gtk_label_set_text(GTK_LABEL(WID(labelNbGlyphs)),text);
    }

endIt:
    // Final round
    gtk_widget_set_sensitive(WID(frameGlyph),1);
    gtk_widget_set_sensitive(WID(frameLoad),0);
    gtk_widget_set_sensitive(WID(buttonStart),0);  
    gtk_widget_set_sensitive(WID(frameBitmap),0);
   // gtk_widget_set_sensitive(WID(Current_Glyph),0); 
    
    if(nbGlyphs && actionSaveGlyph==gtk_dialog_run(GTK_DIALOG(dialog)))
        saveGlyph();
    if(vobsub)
        delete vobsub;
    vobsub=NULL;
    if(out) 
        fclose(out);
    out=NULL;
    gtk_unregister_dialog(dialog);
    gtk_widget_destroy(dialog);
    if(head.next)
        destroyGlyphTree(&head);
    head.next=NULL;
    return 1;

}
Пример #2
0
/**
    \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;  
}
Пример #3
0
/**
    \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;

}
Пример #4
0
/**
    \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;  
}