콘텐츠로 건너뛰기
Home » [c/c++] SMI를 SRT로 컨버팅하기

[c/c++] SMI를 SRT로 컨버팅하기

윈도버전

컴파일 시 큰 문제는 없는데, 대입하는 포인터의 형이 달라서 경고가 뜨는 경우가 있다는데, 내 경우에는 윈도에서 컴파일시 오류가 났다. char* 형에대해 메모리를 할당할 때 캐스팅을하지 않으면 void*로 취급하므로 오류가 나면서 컴파일이 안됐다. 수정~

//Smi to SRT converter.
//(c) George Shuklin
//edited by sooop
// This program is under GPL license. See gpl.txt for detail
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EXTENSION ".srt" //default extension for output
#define BODY "<BODY>"
#define BUFFER 65535 //buffer size
int error (int);//Message from table
void killbr(char *);
int killtags(char *);
int copy_kill_space(char *,char *);
int convert_t(long int, char *);
void BrLine(char *);
int Check_empty(char *);
void cmdCheck(char *);
void change_extension(char *in, char *out);
FILE *input;
FILE *output;
char *buffer;
char *inputline;
char *outputline;
char *temp,*temp2;
char *temp3;
long int time_begin=0;
long int time_end=0;
char time_b[32];
char time_e[32];
int N=1;
int printable=0; //if =1 line printing, =0 - skip
int STRING_LENGTH=70; //breack line ('\n') at this length (or early)
int main( int argc, char* argv[])
{
   int flag=0,flag2;
   char *in_filename=(char*)malloc(255);
   char *out_filename=(char*)malloc(255);
   strcpy(out_filename,"CON");
   printf("\nSmi2srt converter\n");
   printf("(c) George Shuklin\n\n");
   if( argc==1 )//no param
   {
         error( 0 );
         return;
   }
   else
   {
      strcpy( in_filename, argv[1] );
      if( argc>2 )//2,3,4... (exist 2nd param)
      {
         strcpy(out_filename,argv[2]);
      }
      else
      {
        change_extension(in_filename,out_filename);
      }
      if (argc>3) cmdCheck(argv[3]);
   }
   input =fopen(in_filename, "r" );
   output=fopen(out_filename, "w" );
   if( !(int)output ) return error(2);
   if( !(int)input ) return error(1);
   if( !( buffer=(char*)malloc( BUFFER ) ) ) return error( 3 );//mem alloc
   if( !( inputline=(char*)malloc( BUFFER ) )||(int)inputline==-1 ) return error(3);
   if( !( outputline=(char*)malloc( BUFFER ) )||(int)outputline==-1 )return error(3);
   if( !( temp3=(char*)malloc( BUFFER ) )||(int)temp3==-1)return error (3);
   printf ("Converting from %s to %s\n",in_filename,out_filename);
// skip input file till found <body>
// *****************************
// * WARNING! No html comment! * (<!--<body>--> will make a big bug
// *****************************
   while( !flag )//=0 at first time
   {
       if ( !fgets( buffer,  BUFFER, input ) ) return error (4);//exit if no body & EoF
       strupr(buffer);
       if ( strstr( buffer, BODY )  ) flag=1;
   }
//Main loop
   flag=0;
   while (!flag)
   {
       if(flag2)
       {
          flag2=0;
          strcpy(buffer,temp3);
       }
       else
       {
          flag2=0;
          if (!fgets(buffer, BUFFER, input )){flag=1;flag2=1;continue;} //EoF
       }
       *inputline='\0';
       strcpy(inputline,buffer);
       //sttrupr(buffer);
	   toupper(buffer);
       temp=strstr(buffer,"<SYNC START=");
                 if (!temp) continue;
       while(!flag2)//multiline patch
       {
           if (!fgets(buffer, BUFFER, input )){flag=1;flag2=1;continue;} //EoF
           strcpy(temp3,buffer);
           strupr(buffer);
	   temp2=strstr(buffer,"<SYNC START=");
	       if (!temp2) strcat (inputline,temp3);
	   else flag2=1;//End of Sub. line found
       }
//       if (flag) continue;//if EoF
       strcpy(buffer,inputline);
       strupr(buffer);
       temp2=strstr(buffer,"<SYNC START=");
       sscanf( temp2, "<SYNC START=%d",&time_begin);
       if( printable)
       {
            strcpy(time_e,time_b);
            convert_t(time_begin,time_b);
            time_end=time_begin;
            fprintf(output,"%d\n",N++);
            fprintf(output,"%s --> %s\n",time_e,time_b);
            fprintf(output,"%s\n",outputline);
       }
       else
       {
            convert_t(time_begin,time_b);
            strcpy(time_e,time_b);
            time_end=time_begin;
       }
//line converting
       killbr(inputline);
       killtags(inputline);
       copy_kill_space(inputline,outputline);
       BrLine(outputline);
       printable=Check_empty(outputline);
   }
   fclose (input);
   fclose (output);
   free (buffer);
   free (inputline);
   free (outputline);
   printf ("converted a %d lines\n\n",N-1);
   return 0;
}
//functions
int error(int code)
{
   const char errors[][80] = { "use: smi2srt.exe filename.smi [filename.srt] [-l70]  More see in readme.txt","Unable to open input file","Unable to open output file","Memory too low","<body> not found" };
   printf( "Error %d (%s)\n",code, errors[code] );
   return code;
}
void killbr(char * line)
{
   char *temp=strstr(line,"<br>");
   while (temp)
   {
      *temp='\n';
      *(temp+1)=' ';
      *(temp+2)=' ';
      *(temp+3)=' ';
      temp=strstr(temp,"<br>");
   }
}
int killtags(char *line)//kill <tags> and &symbols;
{
   char *temp=line;
   while( *temp )
   {
      if(*temp=='<')
         while (*temp)
         {
            if (*temp=='>'){*temp=' ';break;}
           *(temp++)=' ';
         }
      if(*temp=='&')
         while (*temp)
         {
            if (*(temp+1)==' ') {temp++;break;} //preserve from removing "I & you"
            if (*temp==';'){*temp=' ';break;}
           *(temp++)=' ';
         }
      else temp++;
   }
   return 0;
}
int copy_kill_space(char *in,char *out)
{
   int sp=1;
   while (*in)
   {
       if(*in==' ' && sp==1){in++;continue;}
       if(*in==' ' && sp==0) sp=1; else sp=0;
       *(out++)=*(in++);
   }
   *out='\0';
   return 0;
}
int convert_t(long int number, char *line)
{
    long int temp;
    long int temp2;
    char vals[32][4];
    temp=number/3600000;
    temp2=number-temp*3600000;
    sprintf(vals[0],"%02d",temp);
    temp=temp2/60000;
    temp2=temp2-temp*60000;
    sprintf(vals[1],"%02d",temp);
    temp=temp2/1000;
    temp2=temp2-temp*1000;
    sprintf(vals[2],"%02d",temp);
    temp=temp2;
    sprintf(vals[3],"%03d",temp);
    sprintf(line,"%s:%s:%s.%s",vals[0],vals[1],vals[2],vals[3]);
    return 0;
}
void BrLine(char * line)
{
   int i=0;
   int old=0;
   int flag=0;
   while(1)
   {
      old=i;
      i=i+STRING_LENGTH;
      if (strlen(line)<=i) break;
      while (i>old)
      {
         if (*(line+i)==' ')
         {
            *(line+i)='\n';
            break;
         }
         if (*line=='\n') break;
         i--;
      }
   }
//remove duplicate '\n'
   flag=0;
   if(*line=='\n'){flag=1;*line=' ';}
   while(*line)
   {
       if (*line=='\n')
          if(flag) *line=' ';else flag=1;
       else if(*line!=' ')flag=0;
       line++;
   }
}
int Check_empty(char *line)
//return 0 if line contain only a ' ' (space) or '\n', else return 1
{
   while (*line)
      {
         if(*line!=' ' && *line!='\n') return 1;
         line++;
      }
   return 0;
}
void cmdCheck(char *line)
{
     sscanf(line,"-l%d",&STRING_LENGTH);
}
void change_extension(char *in, char *out)
{
    char *temp;
    strcpy (out,in);
    temp=out+strlen(out);
    while (temp!=out)
    {
        if ( *temp=='.')
        {
            *temp='\0';
            break;
        }
        temp--;
    }
    strcat (out,EXTENSION);
}

맥버전

윈도 버전에서 추가 수정. 문자열을 대문자로 변환하면서 사용된 strupr() 함수는 윈도우용 gcc에 포함된 것으로 보이는 함수이다. 아마 문자열을 대문자로 만들어주는 함수로 보이는데, C표준함수는 아니어서 맥에서는 존재하지 않는 심벌이라는 오류를 내면서 컴파일 되지 않는다.
따라서 이 부분을 대체할 수 있도록 strupr 함수를 추가로 작성했다. 아래 함수를 위 코드에 더하거나 include하여 컴파일하면 성공~

#include <ctype.h>
void strupr(char *somestr)
{
	while(*(somestr+i)!='\0')
	{
		*(somestr+i) = toupper(*(somestr+i));
		somestr++;
	}
}

 

태그: