(* ============================================================================== *) (* === fonction pour lire un pixmap sous ocaml. On aurait pu utiliser === *) (* === camlimages pour cela. Mais, sauf erreur, vu le code de camlimages, je === *) (* === pense que la lecture des pixmaps ne fonctionne pas sous windaube. === *) (* ============================================================================== *) let read_pixmap ficname = (* une fonction pour supprimmer tous les commentaires C d'une string *) let suppress_comment str len = let count = ref 0 and i = ref 0 and in_string = ref false in while !i < len do (* on check si l'on a un caractere different du debut d'un commentaire *) if str.[!i] <> '/' || !in_string then ( if str.[!i] = '"' then in_string := not !in_string; str.[!count] <- str.[!i]; count := !count + 1; i := !i + 1 ) else (* si c'est un commentaire C++, on skippe la fin de la ligne *) if str.[!i+1] = '/' then while str.[!i] <> '\n' do i := !i + 1 done else (* ici on a un commentaire C => on skippe jusqu'au */ *) ( while str.[!i] <> '*' || str.[!i+1] <> '/' do i := !i + 1 done; i := !i + 2 ) done; i := !count; while !i < len do str.[!i] <- ' ' ; i := !i + 1 done; !count in (* une fonction pour creer la table des couleurs. bien entendu, on va utiliser les tables de hachage que nous avons vues en LI213 car c'est une structure particulierement adaptee pour cela. *) let get_colors buff ind nb_col size_col = let deb = ref ind and tab_col = Hashtbl.create nb_col in for i = 1 to nb_col do (* recuperation d'une ligne de couleur *) let deb_line = String.index_from buff !deb '"' in let end_line = String.index_from buff (deb_line + 1) '"' in let line = String.sub buff (deb_line+1) (end_line - deb_line - 1) in let col_name = String.sub line 0 size_col and color = String.sub line size_col (String.length line - size_col) in (* extraction du type de couleur et de sa valeur *) let (col_type,color) = Scanf.sscanf color " %s %s" (fun x y -> (x,y)) in let (r,g,b) = match col_type with | "c" -> if color = "None" then 0,0,0 else if color.[0] <> '#' then failwith ("read_pixmap : xpm symbol color " ^ color ^ " not implemented") else let size = (String.length color - 1) / 3 in let (r,g,b) = (Scanf.sscanf (String.sub color 1 size) "%x" (fun x -> x), Scanf.sscanf (String.sub color (size+1) size) "%x" (fun y -> y), Scanf.sscanf (String.sub color (2*size+1) size) "%x" (fun z -> z)) in (* on transforme cette couleur en 8 bits *) let div = if (size <= 2) then 1 else 16 lsl ((size-3) * 4) in (r/div,g/div,b/div) | _ -> failwith ("read_pixmap : xpm type "^col_type^" not implemented") in Hashtbl.add tab_col col_name (r,g,b); deb := end_line + 1 done; (tab_col,!deb) in (* une fonction pour creer la table des pixels *) let get_pixels buff ind width height tab_col nb_col size_col = let tab_pixels = Array.make (width * height * 3) 0 and deb = ref ind and count = ref 0 in for i = 1 to height do (* lecture d'une ligne de pixels *) let deb_line = String.index_from buff !deb '"' in let end_line = String.index_from buff (deb_line + 1) '"' in let line = String.sub buff (deb_line+1) (end_line - deb_line - 1) in deb := end_line + 1; (* remplissage du tableau de pixels *) for j = 1 to width do let str = String.sub line ((j-1) * size_col) size_col in let (r,g,b) = Hashtbl.find tab_col str in tab_pixels.(!count) <- r; tab_pixels.(!count+1) <- g; tab_pixels.(!count+2) <- b; count := !count+3 done done; tab_pixels in (* ouverture du fichier xpm en lecture *) let in_chan = open_in ficname in let len = in_channel_length in_chan in (* lecture de l'ensemble du fichier *) let buffer = String.make len ' ' in really_input in_chan buffer 0 len; close_in in_chan; (* elimination des commentaires *) let len = suppress_comment buffer len in (* lecture des parametres de l'image (taille, nbcouleurs, etc) *) let ind_deb = String.index_from buffer 0 '"' in let ind_fin = String.index_from buffer (ind_deb+1) '"' in let str = String.sub buffer (ind_deb+1) (ind_fin - ind_deb - 1) in let (width,height,nb_col,size_col) = Scanf.sscanf str " %d %d %d %d" (fun x y z t -> (x,y,z,t)) in (* lecture des couleurs *) let (tab_col,ind_fin) = get_colors buffer (1+(String.index_from buffer ind_fin '\n')) nb_col size_col in (* lecture des pixels *) let pixels = get_pixels buffer (1+(String.index_from buffer ind_fin '\n')) width height tab_col nb_col size_col in (width,height,pixels);;