(***********************************************************************)
(*                                                                     *)
(*                           Objective Caml                            *)
(*                                                                     *)
(*            Jun Furuse, projet Cristal, INRIA Rocquencourt           *)
(*                                                                     *)
(*  Copyright 1999,2000,2001,2002,2001,2002                            *)
(*  Institut National de Recherche en Informatique et en Automatique.  *)
(*  Distributed only by permission.                                    *)
(*                                                                     *)
(***********************************************************************)
open Image
open OImage

let edge (bmp : rgb24) =
  let width = bmp#width in
  let height = bmp#height in
  
  let rgb24 = new rgb24 width height in

  let f x y =
    let center = bmp#get x y in 
    let points = 
      Array.init 3 (fun dx ->
	Array.init 3 (fun dy ->
	  try
	    bmp#get (x+dx-1) (y+dy-1)
	  with
	    Out_of_image -> center))
    in

    let r = ref 0 
    and g = ref 0
    and b = ref 0
    in

    let diff = ref 0
    in

    let add dx dy weight =
      let rgb = points.(dx+1).(dy+1) in
      r := !r + rgb.r * weight;
      g := !g + rgb.g * weight;
      b := !b + rgb.b * weight;
      let dr = center.r - rgb.r
      and dg = center.g - rgb.g
      and db = center.b - rgb.b
      in
      diff := !diff + truncate (sqrt ( float (dr * dr + dg * dg + db * db) ))
    in

    add (-1)   0  1;
    add   1    0  1;
    add   0  (-1) 1;
    add   0    1  1;
    add (-1) (-1) 1;
    add   1  (-1) 1;
    add (-1)   1  1;
    add   1    1  1;
    
    (* 0 <= diff <= 3544 *)
    let cw = 
      let cw = float !diff /. 3544.0 in
      if cw < 0.0 then 0.0 
      else if cw > 1.0 then 1.0
      else cw
    in

    (* we need to emphasize the difference *)
    let cw = truncate (sqrt cw *. 256.0) in
    let newcolor org = 
      let c = org / 8 + cw in
      if c > 255 then 255 else c
    in

    { r= newcolor center.r;
      g= newcolor center.g;
      b= newcolor center.b }
  in
    
  for x = 0 to width -1 do
    for y = 0 to height -1 do
      rgb24#unsafe_set x y (f x y)
    done
  done;
  rgb24
;;

let _ =
  let files = ref [] in
  Arg.parse [] (fun s -> files := s :: !files) "edge files";
  let files = List.rev !files in
  List.iter (fun file -> 
    try
      let rgb =
	let oimage = OImage.load file [] in
	match OImage.tag oimage with
	| Index8 img ->
	    let rgb = img#to_rgb24 in
	    img#destroy;
	    rgb
	| Index16 img ->    
	    let rgb = img#to_rgb24 in
	    img#destroy;
	    rgb
	| Rgb24 img -> img
	| _ -> raise (Invalid_argument "not supported")
      in
      let rgb' = edge rgb in
      
      let get_extension s =
  	let dotpos = String.rindex s '.' in
  	String.sub s (dotpos + 1) (String.length s - dotpos - 1)
      in

      let ext = get_extension file in
      let body = String.sub file 0 
	  (String.length file - String.length ext - 1) in 
      let outfile = body ^ ".edge.jpg" in

      rgb'#save outfile (Some Jpeg) [];
    with _ -> ()) files


  
