--- /dev/null
+
+Look at Bigarray module:
+
+ http://caml.inria.fr/pub/docs/manual-ocaml/manual043.html
+ http://pauillac.inria.fr/cdrom/www/caml/ocaml/htmlman/manual042.html
+ http://jhenrikson.org/forklift/checkout/doc/higher_order.html
+
+From :
+
+ http://webcvs.freedesktop.org/cairo/cairo-ocaml/test/basket.ml?revision=1.7&view=markup
+
+ begin
+ prerr_endline "Bigarray, PPM and PNG (ARGB32) " ;
+ let arr =
+ Bigarray.Array2.create Bigarray.int32 Bigarray.c_layout
+ (int_of_float y_inches * 72) (int_of_float x_inches * 72) in
+ Bigarray.Array2.fill arr 0xffffffl ;
+ let s = Cairo_bigarray.of_bigarr_32 ~alpha:true arr in
+ let c = Cairo.create s in
+ draw c ;
+ do_file_out "basket.ppm"
+ (fun oc -> Cairo_bigarray.write_ppm_int32 oc arr) ;
+ Cairo_png.surface_write_to_file s "basket.png"
+ end
+
+
+===========================================================================
+
+Actually many scientific OCaml libraries use the bigarray module. It
+is also the case of Lacaml (a binding to LAPACK) or FFTW (a binding
+to, hum, FFTW!).
+
+Now I do not understand why you could not have a function
+
+ val read_array1 : t -> ('a,'b,'c) Bigarray.Array1.t -> int
+
+ Sndfile.read_array1 f a read data from the file f into the supplied
+ bigarray a and return the number of float values read.
+
+ For multi-channel files, the array length must be an integer
+ multiple of the number of channels.
+
+The idea is that the read function adapts the type of the bigarray
+passed (if possible; if not, raise an exception). One could also
+require that a Bigarray.Array2.t is used with one of its dimensions
+being the number of channels (if possible allowing easy slicing to
+extract a given channel).
+
+Same goes for a write function.
+
+BTW, the last part of the comment is a bit laconic: one wonders "or
+what ?". An exception is raised ? The array slots with higher
+indexes are never filled ? Garbage can be returned ? etc.
+
+> I was particularly interested if there was any utility to providing
+> functions for accessing shorts or ints. So far noone has come up
+> with a need for these.
+
+I did not follow thoroughly the discussion but there is an Int32
+module and the C interface has "Int32_val(v)" and "Int64_val(v)". To
+create a caml Int32.t (resp. Int64.t), you must allocate a custom
+block containing an "int32" (resp. int64). See section 18 of the
+manual.
+
+
+
+===========================================================================
+
+
+(* cairo_bigarray.mli *)
+(*
+
+open Bigarray
+
+val of_bigarr :
+ ('a, 'b, c_layout) Array2.t -> Cairo.format ->
+ width:int -> height:int -> stride:int -> Cairo.image_surface
+
+val of_bigarr_32 : alpha:bool -> (int32, int32_elt, c_layout) Array2.t -> Cairo.image_surface
+val of_bigarr_24 : (int, int_elt, c_layout) Array2.t -> Cairo.image_surface
+val of_bigarr_8 : (int, int8_unsigned_elt, c_layout) Array2.t -> Cairo.image_surface
+
+val write_ppm_int32 : out_channel -> (int32, int32_elt, c_layout) Array2.t -> unit
+val write_ppm_int : out_channel -> (int, int_elt, c_layout) Array2.t -> unit
+
+*)
+
+
+
+
+
+(* cairo_bigarray.ml *)
+(*
+
+open Bigarray
+
+external bigarray_kind_float : ('a, 'b, c_layout) Array2.t -> bool
+ = "ml_bigarray_kind_float"
+external bigarray_byte_size : ('a, 'b, c_layout) Array2.t -> int
+ = "ml_bigarray_byte_size"
+
+external image_surface_create :
+ ('a, 'b, c_layout) Array2.t ->
+ Cairo.format -> width:int -> height:int -> stride:int ->
+ Cairo.image_surface = "ml_cairo_image_surface_create_for_data"
+
+
+let of_bigarr arr format ~width ~height ~stride =
+ if bigarray_kind_float arr
+ then invalid_arg "wrong Bigarray kind" ;
+ if bigarray_byte_size arr < stride * height
+ then invalid_arg "Bigarray too small" ;
+ image_surface_create arr format width height stride
+
+let of_bigarr_32 ~alpha (arr : (int32, int32_elt, c_layout) Array2.t) =
+ let h = Array2.dim1 arr in
+ let w = Array2.dim2 arr in
+ of_bigarr arr
+ (if alpha then Cairo.FORMAT_ARGB32 else Cairo.FORMAT_RGB24)
+ w h (4 * w)
+
+let of_bigarr_24 (arr : (int, int_elt, c_layout) Array2.t) =
+ if Sys.word_size <> 32
+ then failwith "your ints have 63 bits" ;
+ let h = Array2.dim1 arr in
+ let w = Array2.dim2 arr in
+ of_bigarr arr
+ Cairo.FORMAT_RGB24
+ w h (4 * w)
+
+let of_bigarr_8 (arr : (int, int8_unsigned_elt, c_layout) Array2.t) =
+ let h = Array2.dim1 arr in
+ let w = Array2.dim2 arr in
+ of_bigarr arr
+ Cairo.FORMAT_A8
+ w h w
+
+let output_pixel oc p =
+ let r = (p lsr 16) land 0xff in
+ output_byte oc r ;
+ let g = (p lsr 8) land 0xff in
+ output_byte oc g ;
+ let b = p land 0xff in
+ output_byte oc b
+
+let write_ppm_int32 oc (arr : (int32, int32_elt, c_layout) Array2.t) =
+ let h = Array2.dim1 arr in
+ let w = Array2.dim2 arr in
+ Printf.fprintf oc "P6 %d %d 255\n" w h ;
+ for i=0 to pred h do
+ for j=0 to pred w do
+ output_pixel oc (Int32.to_int arr.{i, j})
+ done
+ done ;
+ flush oc
+
+let write_ppm_int oc (arr : (int, int_elt, c_layout) Array2.t) =
+ let h = Array2.dim1 arr in
+ let w = Array2.dim2 arr in
+ Printf.fprintf oc "P6 %d %d 255\n" w h ;
+ for i=0 to pred h do
+ for j=0 to pred w do
+ output_pixel oc arr.{i, j}
+ done
+ done ;
+ flush oc
+
+*)