diff --git a/epitass.ml b/epitass.ml index 7229f4b1d6318118c627bc3716254734afd300bf..1f7c4a31cf7fcfef6d5a86a3b8e74a6de98e9315 100644 --- a/epitass.ml +++ b/epitass.ml @@ -6,9 +6,7 @@ \*************************************************************) let outch = ref stdout in -let overlap_frame_mode = ref false in let font = ref "Arial" in -let outline_color = ref (0,0,0,0) in let bold = ref false in let italic = ref false in let underline = ref false in @@ -26,59 +24,294 @@ let marginr= ref 10 in let default_font_size = ref 40 in let default_primary_color = ref (0,0,127,255) in let default_secondary_color = ref (0,255,255,255) in -let default_back_color = ref (0,0,0,0) in +let default_outline_color = ref (0,0,0,0) in let default_marginv = ref 10 in let default_alpha = ref 0 in -let framerate= ref 25 in +let framerate= ref 25. in let color_threshold = ref 300 in +let overlap_frame_mode = ref false in let override_style_mode = ref false in let override_alpha_mode = ref true in let backup_first_style_mode = ref true in -let guess_backcolor_mode= ref true in +let guess_outline_color_mode= ref true in let warning_following_syllable_mode = ref false in +let shadow_color = ref (0,0,0,0) in let playResX = ref 800 in let playResY = ref 600 in let audio_file = ref "?video" in let video_file = ref "" in + +let print_mode m = if m then "set" else "unset" in + +let set_color_option cn cref el = + let cnn = + (match cn with + |1 -> "default primary" + |2 -> "default secondary" + |3 -> "default outline" + |_ -> "shadow" + ) in + ( + (Printf.sprintf "-c%d" cn), + Arg.String (fun cs -> + let hexa_digit_to_int h = + let a = Char.code h in + if a<=57 && a>=48 + then + a - 48 + else if a>=65 && a<=70 + then + a - 55 + else + raise Not_found + in + let l = String.length cs in + try + cref := + if (l != 6) && (l != 8) + then raise Not_found + else if l=6 + then + (!default_alpha, (hexa_digit_to_int cs.[0])*16+(hexa_digit_to_int cs.[1]), (hexa_digit_to_int cs.[2])*16+(hexa_digit_to_int cs.[3]), (hexa_digit_to_int cs.[4])*16+(hexa_digit_to_int cs.[5])) + else + ((hexa_digit_to_int cs.[0])*16+(hexa_digit_to_int cs.[1]), (hexa_digit_to_int cs.[2])*16+(hexa_digit_to_int cs.[3]), (hexa_digit_to_int cs.[4])*16+(hexa_digit_to_int cs.[5]), (hexa_digit_to_int cs.[6])*16+(hexa_digit_to_int cs.[7])) + with Not_found -> + Printf.eprintf "[Warning] Wrong color for %s. Expected format: AABBGGRR | BBGGRR where GG is green field in hexadecimal notation (AA for alpha, BB for blue, RR for red), example: 00FF9A11." cnn + ), + ( + let c2s (a,b,g,r) = + let z i = if i<10 then "0" else "" in + Printf.sprintf "%s%X%s%X%s%X%s%X" (z a) a (z b) b (z g) g (z r) r in + Printf.sprintf "[AA]BBGGRR\tSet %s color (default : %s), XX is Alpha/Blue/Green/Red field in hexadecimal notation, default_alpha used (should be set before) if AA not specified.%s" cnn (c2s !cref) el + ) + ) +in + + +let set_color_field_option cn fn cref el = + let fnn = + (match fn with + |1 -> "blue" + |2 -> "green" + |3 -> "red" + |_ -> "alpha" + ) in + let cnn = + (match cn with + |1 -> "default primary" + |2 -> "default secondary" + |3 -> "default outline" + |_ -> "shadow" + ) in + ( + (Printf.sprintf "-c%d%c" cn + (match fn with + |1 -> 'b' + |2 -> 'g' + |3 -> 'r' + |_ -> 'a' + ) + ), + Arg.Int (fun ncf -> + if ncf < 0 + then + Printf.eprintf "[Warning] %s field given for %s color is negative." fnn cnn + else if ncf > 255 + then + Printf.eprintf "[Warning] %s field given for %s color is greater than 255." fnn cnn + else + cref := match !cref with (a,b,g,r) -> + (match fn with + |1 -> (a,ncf,g,r) + |2 -> (a,b,ncf,r) + |3 -> (a,b,g,ncf) + |_ -> (ncf,b,g,r) + ) + ), + (Printf.sprintf "%s\tSet %s field of %s color (default : %d), value between 0%s and 255%s.%s" fnn fnn cnn + (match !cref with (a,b,r,g) -> + (match fn with + |1 -> b + |2 -> g + |3 -> r + |_ -> a + ) + ) + (if fn=0 then " (opaque)" else "") + (if fn=0 then " (transparent)" else "") + el + ) + ) +in + + (*let _ = prerr_endline "[Info] Begin\n" in*) Arg.parse (*Named parameter*) [ (*TODO one option by parameter*) + + (*Main options:*) + + ("--v1", Arg.Unit + (fun f -> + overlap_frame_mode := true + ), + "\t\tSet modes for v1 (set: overlap frame mode)."); + + ("--v2", Arg.Unit + (fun f -> + overlap_frame_mode := false + ), + "\t\tSet modes for v2 (unset: overlap frame mode)."); + ("-o", Arg.String (fun f -> outch := open_out f ), - "Print the ass result in the given file instead of standard output."); - ("-overlap_frame_mode", Arg.Unit + "file\tPrint the ass result in the given file instead of standard output."); + + ("-video_file", Arg.String (fun s -> - overlap_frame_mode := true + video_file := s + ), + (Printf.sprintf "video\tSet the file name of the video linked to the subtitles (default : %s)." !video_file)); + + ("-video", Arg.String + (fun s -> + video_file := s + (*TODO framerate, playRes*) + ), + (Printf.sprintf "video\tSet the file name of the video linked to the subtitles (default : %s) and set other options (None currently)." !video_file)); + + ("-framerate", Arg.Float + (fun f -> + framerate := f ), - (String.concat "" ["Set overlap frame mode : {0}{5} and {5}{10} will not end in the same cluster. Useful for v1"])); + (Printf.sprintf "framerate\tSet the framerate of the video linked to the subtitles (default : %f), can be a float." !framerate)); + + (* + ("-playres", Arg.String + (fun s -> + TODO + ), + (Printf.sprintf "x*y\tSet the dimensions of the video linked to the subtitles (default : %d*%d).\n\nStyle options:" !playResX !playResY));*) + + ("-playresx", Arg.Int + (fun x -> + playResX := x + ), + (Printf.sprintf "x\tSet the x dimension of the video linked to the subtitles (default : %d)." !playResX)); + + ("-playresy", Arg.Int + (fun x -> + playResX := x + ), + (Printf.sprintf "y\tSet the y dimension of the video linked to the subtitles (default : %d).\n\n\nStyle options:\n" !playResY)); + + (*Style options:*) + ("-font", Arg.String (fun f -> font := f ), - (String.concat "" ["Set the font (default : ";!font;")."])); - ("-framerate", Arg.Int - (fun f -> - framerate := f + (Printf.sprintf "font\tSet the font (default : %s)." !font)); + + ("-font_size", Arg.Int + (fun fs -> + default_font_size := fs ), - (String.concat "" ["Set the framerate of the video linked to the subtitles (default : ";string_of_int !framerate;")."])); - ("-video", Arg.String + (Printf.sprintf "size\tSet the default font size (default : %d)." !default_font_size)); + + ("-marginv", Arg.Int + (fun mv -> + default_marginv := mv + ), + (Printf.sprintf "marginV\tSet the default vertical margin (default : %d). Used for top vertical shift and line space.\n" !default_font_size)); + + ("-default_alpha", Arg.Int + (fun a -> + default_alpha := a + ), + (Printf.sprintf "alpha\tSet/unset defaul alpha (default: %d), between 0 (opaque) and 255 (transparent), used in override_alpha_mode and for default colors when unspecified." !default_alpha)); + + (set_color_option 1 default_primary_color ""); + (set_color_option 2 default_secondary_color ""); + (set_color_option 4 default_outline_color "\n\n\nGuess Style options:\n"); + + (*Guess style options*) + ("--osm", Arg.Unit + (fun () -> + override_style_mode := not !override_style_mode + ), + (Printf.sprintf "\tSet/unset override style mode (default: %s): default style will be applied to all the lines when set, style should be guessed from the toyunda file when unset." (print_mode !override_style_mode))); + + ("--bfsm", Arg.Unit + (fun () -> + backup_first_style_mode := not !backup_first_style_mode + ), + (Printf.sprintf "\tSet/unset backup first style mode (default: %s): when this program can't guess the style of a line, it will apply the first style found if set, and the default style (specified by following options) if unset, ignored if override style mode is unset." (print_mode !overlap_frame_mode))); + + ("--gom", Arg.Unit + (fun () -> + guess_outline_color_mode := not !guess_outline_color_mode + ), + (Printf.sprintf "\tSet/unset guess outline color mode (default: %s): if set and override style mode unset, back color will be guessed from the two other colors, default style used otherwise." (print_mode !guess_outline_color_mode))); + + ("--oam", Arg.Unit + (fun () -> + override_alpha_mode := not !override_alpha_mode + ), + (Printf.sprintf "\tSet/unset override alpha mode (default: %s): alpha values are ignored and replaced by default alpha value when set." (print_mode !overlap_frame_mode))); + + ("-color_threshold", Arg.Int + (fun ct -> + color_threshold := ct + ), + (Printf.sprintf "threshold\tSet the color threshold (default : %d). This value is used when guessing colors to avoid primary colors and secondary colors from being too close: |c1b-c2b|+|c1g-c2g|+|c1r-c2r|>=threshold.\n\n\nOther options:\n" !default_font_size)); + + + (*Other options:*) + ("--ofm", Arg.Unit (fun s -> - video_file := s + overlap_frame_mode := not !overlap_frame_mode ), - (String.concat "" ["Set the file name of the video linked to the subtitles (default : ";!video_file;")."])); - (*TODO - ("--guess_parameters_from_video", Arg.Unit + (Printf.sprintf "\tSet/unset overlap frame mode (default: %s): {0}{5} and {5}{10} will end in different clusters only when set." (print_mode !overlap_frame_mode))); + ("--wfsm", Arg.Unit (fun s -> + warning_following_syllable_mode := not !warning_following_syllable_mode ), - "Give the file name of the video linked to the subtitles.");*) + (Printf.sprintf "\tSet/unset warning following syllable mode (default: %s): if set prints a warning when the syllables' frames in a line doesn't match.\n" (print_mode !overlap_frame_mode))); + + (set_color_field_option 1 0 default_primary_color ""); + (set_color_field_option 1 1 default_primary_color ""); + (set_color_field_option 1 2 default_primary_color ""); + (set_color_field_option 1 3 default_primary_color "\n"); + + (set_color_field_option 2 0 default_secondary_color ""); + (set_color_field_option 2 1 default_secondary_color ""); + (set_color_field_option 2 2 default_secondary_color ""); + (set_color_field_option 2 3 default_secondary_color "\n"); + + (set_color_field_option 3 0 default_outline_color ""); + (set_color_field_option 3 1 default_outline_color ""); + (set_color_field_option 3 2 default_outline_color ""); + (set_color_field_option 3 3 default_outline_color "\n"); + + (set_color_option 4 shadow_color " This color will never be guessed."); + (set_color_field_option 4 0 shadow_color ""); + (set_color_field_option 4 1 shadow_color ""); + (set_color_field_option 4 2 shadow_color ""); + (set_color_field_option 4 3 shadow_color "\n"); ] + + + + + (fun file_name -> (* For each file passed as an anonymous parameter *) @@ -99,9 +332,9 @@ Arg.parse (*let _ = prerr_endline "[Info] Generate styles and events\n" in*) let (style_list,event_list) = Toyunda_raw_to_v4p_ass.create_ass_events_and_styles - !font !outline_color !bold !italic !underline !strike_out !scalex !scaley !spacing !angle !borderstyle !outline !shadow !alignment !marginl !marginr - !default_font_size !default_primary_color !default_secondary_color !default_back_color !default_marginv !default_alpha !framerate - !color_threshold !override_style_mode !override_alpha_mode !backup_first_style_mode !guess_backcolor_mode !warning_following_syllable_mode + !font !shadow_color !bold !italic !underline !strike_out !scalex !scaley !spacing !angle !borderstyle !outline !shadow !alignment !marginl !marginr + !default_font_size !default_primary_color !default_secondary_color !default_outline_color !default_marginv !default_alpha !framerate + !color_threshold !override_style_mode !override_alpha_mode !backup_first_style_mode !guess_outline_color_mode !warning_following_syllable_mode sorted_toyunda positioned_lines in (*let _ = prerr_endline "[Info] Generate ass\n" in*) @@ -110,5 +343,6 @@ Arg.parse (*let _ = prerr_endline "[Info] Print ass\n" in*) Tree_v4p_ass.fprint_kara !outch ass ) -(String.concat "" ["Usage : "; Sys.argv.(0); " [ options ] file ..."]) + +(String.concat "" ["\nUsage: "; Sys.argv.(0); " [ options ] file ...\n\nMain options:\n"]) diff --git a/epitass.standalone b/epitass.standalone index c1f52bcba90a018786f8fa117c76cc2075fc5ca3..303e3a335076b5571b4a95b9ea6e5abe259196a1 100755 Binary files a/epitass.standalone and b/epitass.standalone differ diff --git a/lexer_toyunda_raw.mll b/lexer_toyunda_raw.mll index 63ffdab9cd844c3f42be92ef3f1685037e0de1f5..4bd41ba21177e43e5fbafdfc9093acf45966af3a 100644 --- a/lexer_toyunda_raw.mll +++ b/lexer_toyunda_raw.mll @@ -20,7 +20,7 @@ let hexadig = ['0'-'9' 'A'-'Z'] let hexanum = hexadig hexadig let colorField = '$' hexanum hexanum hexanum (hexanum)? let ddrInstruction = ['<''>''^''v']* -let not_special_character_string = [^'\n''\r''<''>''^''v''0'-'9''{''}''|'':'','' ''\128'-'\254']+ +let not_special_character_string = [^'\n''\r''<''>''^''v''0'-'9''{''}''|'':'','' ']+ (* Rules section *) @@ -47,7 +47,7 @@ rule entrypoint = parse | "{b:" { BITMAP_OPTION } | "{d:" { DDR_OPTION } | eof { EOF } - | ['\128'-'\254']* as nscs { let _ = Printf.eprintf "[Warning] Latin-1 / Extended ASCII caracter encountered : \"%s\"\n" (String.escaped nscs) in NSCS(nscs) } +(*| ['\128'-'\254']* as nscs { let _ = Printf.eprintf "[Warning] Latin-1 / Extended ASCII caracter encountered : \"%s\"\n" (String.escaped nscs) in NSCS(nscs) }*) | not_special_character_string as nscs { (*let _ = Printf.eprintf "[test] lexer : \"%s\"\n" (String.escaped nscs) in*) NSCS(nscs) } (*See "garbage" part of parser*) | _ as invalid_char { raise (Invalid_char invalid_char) } diff --git a/toyunda_raw_to_v4p_ass.ml b/toyunda_raw_to_v4p_ass.ml index 21707f7e613ac14b800c04199f9dec32d7c18783..56cc70515854530c92522c6195a07e959dc4a9ae 100644 --- a/toyunda_raw_to_v4p_ass.ml +++ b/toyunda_raw_to_v4p_ass.ml @@ -293,7 +293,10 @@ let utf8_of_latin1 s = else if c='\253' then "ý" else if c='\254' then "þ" else if c='\255' then "ÿ" - else String.make 1 c + else + let s= String.make 1 c in + let _ = Printf.eprintf "[Warning] unrecognised character : \'%s\'\n" (String.escaped s) in + s in uol (i+1) (String.concat "" [ns;nc]) with Invalid_argument _ -> ns in @@ -312,9 +315,9 @@ let utf8_of_latin1 s = type style = int(*id*) * int(*font_size*) * color(*primaryColour*) * color(*secondaryColour*) let create_ass_events_and_styles -font outline_color bold italic underline strike_out scalex scaley spacing angle borderstyle outline shadow alignment marginl marginr -default_font_size default_primary_color default_secondary_color default_back_color default_marginv default_alpha framerate -color_threshold override_style_mode override_alpha_mode backup_first_style_mode guess_backcolor_mode warning_following_syllable_mode +font shadow_color bold italic underline strike_out scalex scaley spacing angle borderstyle outline shadow alignment marginl marginr +default_font_size default_primary_color default_secondary_color default_outline_color default_marginv default_alpha framerate +color_threshold override_style_mode override_alpha_mode backup_first_style_mode guess_outline_color_mode warning_following_syllable_mode sorted_toyunda positioned_lines = (*For each pipe number*) @@ -447,18 +450,18 @@ sorted_toyunda positioned_lines = ( ((if override_alpha_mode then default_alpha else a2),b2,g2,r2), ((if override_alpha_mode then default_alpha else a1),b1,g1,r1), - (if guess_backcolor_mode then ((if override_alpha_mode then default_alpha else (a1+a2)/2),255 - ((b1+b2)/2),255 - ((g1+g2)/2),255 - ((r1+r2)/2)) else default_back_color) + (if guess_outline_color_mode then ((if override_alpha_mode then default_alpha else (a1+a2)/2),255 - ((b1+b2)/2),255 - ((g1+g2)/2),255 - ((r1+r2)/2)) else default_outline_color) ) - | _ -> (default_primary_color,default_secondary_color,default_back_color) + | _ -> (default_primary_color,default_secondary_color,default_outline_color) in (*let _ = prerr_endline "[Info] add_style\n" in*) - let rec add_style primary_color secondary_color back_color size sl i = match sl with + let rec add_style primary_color secondary_color outline_color size sl i = match sl with |[] -> let stylename = String.concat "" ["GeneratedStyle"; string_of_int i] in ([( stylename,font,size, - primary_color, secondary_color,outline_color,back_color, + primary_color, secondary_color,outline_color,shadow_color, bold,italic,underline,strike_out,scalex,scaley,spacing,angle, borderstyle,outline,shadow,alignment,marginl,marginr,default_marginv,1,[] )],stylename) @@ -510,6 +513,11 @@ sorted_toyunda positioned_lines = in let event_list = List.fold_left (fun el (stylename, sfb, efb, pn, b, lb, syllable_list) -> + let cs_of_frame f = + int_of_float ( + ((float_of_int (f * 100)) /. framerate) -. 0.5 + ) + in let rec time b syllable_list first_frame expected_frame already_timed cursor_count = match syllable_list with | [] -> (first_frame, expected_frame, (String.concat "" [ @@ -529,9 +537,9 @@ sorted_toyunda positioned_lines = else if warning_following_syllable_mode then Printf.eprintf "[Warning] Expected next syllable frame %d, got %d.\n" expected_frame sf else () in - (first_frame, String.concat "" ["{\\k";string_of_int ((sf-expected_frame)*100/framerate);"}"]) + (first_frame, String.concat "" ["{\\k";string_of_int (cs_of_frame (sf-expected_frame));"}"]) else (first_frame,"") in - let kstring = string_of_int ((ef-sf)*100/framerate) in + let kstring = string_of_int (cs_of_frame (ef-sf)) in (*let _ = Printf.eprintf "[Test] kstring %s for ef-sf = %d-%d = %d | expected_frame=%d first_frame=%d \n" kstring ef sf (ef-sf) expected_frame first_frame in*) time b slt first_frame ef ( String.concat "" [ @@ -543,8 +551,8 @@ sorted_toyunda positioned_lines = ) yc in let (ff,ef,tb) = time b syllable_list 0 0 "" 0 in - let ff = ff*100/framerate in - let ef = ef*100/framerate in + let ff = cs_of_frame ff in + let ef = cs_of_frame ef in ( 0, Tree_v4p_ass.cs_to_event_time (max (ff-90) 0), Tree_v4p_ass.cs_to_event_time (ef+10), stylename,"", marginl, marginr,(default_marginv + pn*(default_font_size+default_marginv)/2), @@ -559,10 +567,10 @@ sorted_toyunda positioned_lines = let style_list = if backup_first_style_mode && override_style_mode then match style_list with - | default_style::((stylename,_,size,c1,c2,_,c4,_,_,_,_, _,_,_,_,_,_,_,_,_,_,_,_,_)::slt) -> + | default_style::((stylename,_,size,c1,c2,c3,_,_,_,_,_, _,_,_,_,_,_,_,_,_,_,_,_,_)::slt) -> ( "Default",font,size, - c1,c2,outline_color,c4, + c1,c2,c3,shadow_color, bold,italic,underline,strike_out,scalex,scaley,spacing,angle, borderstyle,outline,shadow,alignment,marginl,marginr,default_marginv,1,[] )::slt @@ -573,7 +581,7 @@ sorted_toyunda positioned_lines = ) sorted_toyunda ([( "Default",font,default_font_size, - default_primary_color,default_secondary_color,outline_color,default_back_color, + default_primary_color,default_secondary_color,default_outline_color,shadow_color, bold,italic,underline,strike_out,scalex,scaley,spacing,angle, borderstyle,outline,shadow,alignment,marginl,marginr,default_marginv,1,[] )], [])