From 164e000c3e7eec26495141d4ec56b0b8a3ec87be Mon Sep 17 00:00:00 2001
From: Seipas <seipas@net-c.com>
Date: Sat, 4 Feb 2017 17:25:04 +0100
Subject: [PATCH] Main options added + Options sorted + Correction confusion
 back/outline/shadow color + Correction non-ascii

---
 epitass.ml                | 282 ++++++++++++++++++++++++++++++++++----
 epitass.standalone        | Bin 459977 -> 465009 bytes
 lexer_toyunda_raw.mll     |   4 +-
 toyunda_raw_to_v4p_ass.ml |  38 +++--
 4 files changed, 283 insertions(+), 41 deletions(-)

diff --git a/epitass.ml b/epitass.ml
index 7229f4b..1f7c4a3 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
GIT binary patch
delta 14681
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
Yo3`TpYv{a=i#qV9k3W|GnUkmgAAgzZ>i_@%

delta 10141
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
MMX7Pok_4Ofzs_n3-T(jq

diff --git a/lexer_toyunda_raw.mll b/lexer_toyunda_raw.mll
index 63ffdab..4bd41ba 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 21707f7..56cc705 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,[]
   )], [])
-- 
GitLab