Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file rgb24.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377(***********************************************************************)(* *)(* Objective Caml *)(* *)(* François Pessaux, projet Cristal, INRIA Rocquencourt *)(* Pierre Weis, projet Cristal, INRIA Rocquencourt *)(* Jun Furuse, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1999-2004, *)(* Institut National de Recherche en Informatique et en Automatique. *)(* Distributed only by permission. *)(* *)(***********************************************************************)(* $Id: rgb24.ml,v 1.7 2009/07/04 03:39:28 furuse Exp $ *)openUtilmoduleE=structopenColortypet=Color.rgbletbytes_per_pixel=3letgetstrpos={r=str@%pos;g=str@%pos+1;b=str@%pos+2}letsetstrpost=str<<pos&char_of_intt.r;str<<pos+1&char_of_intt.g;str<<pos+2&char_of_intt.bletmaket=letstr=Bytes.createbytes_per_pixelinsetstr0t;strendmoduleRI=Genimage.MakeRawImage(E)typerawimage=RI.ttypeelt=Color.rgbtypet={width:int;height:int;rawimage:RI.t;mutableinfos:Info.infolist}moduleC=structtyperawimage=RI.ttypecontainer=tletrawimagex=x.rawimageletcreate_defaultwidthheightrawimage={width=width;height=height;rawimage=rawimage;infos=[]}letcreate_duplicatesrcwidthheightrawimage={width=width;height=height;rawimage=rawimage;infos=src.infos}endmoduleIMAGE=Genimage.Make(RI)(C)letcreate_withwidthheightinfosdata={width=width;height=height;rawimage=RI.create_withwidthheightdata;infos=infos}letcreate_with_scanlineswidthheightinfosdata={width=width;height=height;rawimage=RI.create_with_scanlineswidthheightdata;infos=infos;}letrawimage=C.rawimageletcreate=IMAGE.createletmake=IMAGE.makeletdump=IMAGE.dumpletunsafe_access=IMAGE.unsafe_accessletget_strip=IMAGE.get_stripletset_strip=IMAGE.set_stripletget_scanline=IMAGE.get_scanlineletget_scanline_ptr=IMAGE.get_scanline_ptrletset_scanline=IMAGE.set_scanlineletunsafe_get=IMAGE.unsafe_getletunsafe_set=IMAGE.unsafe_setletget=IMAGE.getletset=IMAGE.setletdestroy=IMAGE.destroyletcopy=IMAGE.copyletsub=IMAGE.subletblit=IMAGE.blitletmap=IMAGE.mapletblocks=IMAGE.blocksletdump_block=IMAGE.dump_blockopenColor(* image resize with smoothing *)(* good result for reducing *)letresize_reduceprogimgnwnh=letnewimage=createnwnhinletxscale=floatnw/.floatimg.widthinletyscale=floatnh/.floatimg.heightinletxs=Array.initnw(funx->letsx=truncate(floatx/.xscale)inletex=truncate((floatx+.0.99)/.xscale)inletdx=ex-sx+1in(sx,ex,dx))inletys=Array.initnh(funy->letsy=truncate(floaty/.yscale)inletey=truncate((floaty+.0.99)/.yscale)inletdy=ey-sy+1in(sy,ey,dy))inforx=0tonw-1doletsx,ex,dx=xs.(x)infory=0tonh-1doletsy,ey,dy=ys.(y)inletsize=dx*dyinletsr=ref0andsg=ref0andsb=ref0inforxx=sxtoexdoforyy=sytoeydoletc=unsafe_getimgxxyyinsr:=!sr+c.r;sg:=!sg+c.g;sb:=!sb+c.bdonedone;unsafe_setnewimagexy{r=!sr/size;g=!sg/size;b=!sb/size;}done;matchprogwith|Somep->p(float(x+1)/.floatnw)|None->()done;newimageletresize_enlargeprogimgnwnh=letnewimage=createnwnhinletxscale=floatnw/.floatimg.widthinletyscale=floatnh/.floatimg.heightinletww=truncate(ceilxscale)andwh=truncate(ceilyscale)inletweight=Array.initww(funx->Array.initwh(funy->letx0=x-ww/2andy0=y-wh/2inletx1=x0+ww-1andy1=y0+wh-1inleta=Array.init3(funxx->Array.init3(funyy->letmx0=(xx-1)*wwandmy0=(yy-1)*whinletmx1=mx0+ww-1andmy1=my0+wh-1inletcx0=ifx0<mx0thenmx0elsex0inletcy0=ify0<my0thenmy0elsey0inletcx1=ifx1>mx1thenmx1elsex1inletcy1=ify1>my1thenmy1elsey1inletdx=cx1-cx0+1anddy=cy1-cy0+1inletdx=ifdx<0then0elsedxanddy=ifdy<0then0elsedyindx*dy))ina))inletwsum=Array.initww(funx->Array.initwh(funy->letsum=ref0inArray.iter(Array.iter(funw->sum:=!sum+w))weight.(x).(y);if!sum=0thenraise(Failure"resize_enlarge wsum");!sum))inletxs=Array.initimg.width(funx->letsx=truncate(floatx*.xscale)inletex=truncate(float(x+1)*.xscale)-1inletdx=ex-sx+1inifdx>wwthenraise(Failure"resize_enlarge");(sx,ex,dx))inletys=Array.initimg.height(funy->letsy=truncate(floaty*.yscale)inletey=truncate((float(y+1))*.yscale)-1inletdy=ey-sy+1inifdy>whthenraise(Failure"resize_enlarge");(sy,ey,dy))inletquerycxy=ifx<0||y<0||x>=img.width||y>=img.heightthencelseunsafe_getimgxyinfory=0toimg.height-1doletsy,_ey,dy=ys.(y)inforx=0toimg.width-1doletsx,_ex,dx=xs.(x)inletcolors=letc=unsafe_getimgxyinArray.init3(fundx->Array.init3(fundy->queryc(x+dx-1)(y+dy-1)))inforxx=0todx-1doforyy=0tody-1doletsr=ref0andsg=ref0andsb=ref0inletweight=weight.(xx).(yy)inletwsum=wsum.(xx).(yy)inforxxx=0to2doforyyy=0to2doletc=colors.(xxx).(yyy)insr:=!sr+c.r*weight.(xxx).(yyy);sg:=!sg+c.g*weight.(xxx).(yyy);sb:=!sb+c.b*weight.(xxx).(yyy);donedone;letr=!sr/wsumandg=!sg/wsumandb=!sb/wsuminunsafe_setnewimage(sx+xx)(sy+yy){r=r;g=g;b=b;}donedonedone;matchprogwith|Somep->p(float(y+1)/.floatimg.height)|None->()done;newimageletresizeprogimgnwnh=letxscale=floatnw/.floatimg.widthinletyscale=floatnh/.floatimg.heightinifxscale>=1.0&&yscale>=1.0thenresize_enlargeprogimgnwnhelseifxscale<=1.0&&yscale<=1.0thenresize_reduceprogimgnwnhelseresize_reduceprogimgnwnh(*
let project prog img fill proj proj' smooth =
if smooth < 0 then raise (Invalid_argument "project");
(* calculation of the destination image size *)
let w = 0.49 in
let w' = 1.0 -. w in
let topleft = proj (-. w) (-. w) in
let topright = proj (float (img.width - 1) +. w) (-. w) in
let bottomleft = proj (-. w) (float (img.height - 1) +. w) in
let bottomright = proj (float (img.width - 1) +. w) (float (img.height - 1) +. w)
in
let minx, miny, maxx, maxy =
let minx = ref (fst topleft)
and miny = ref (snd topleft)
and maxx = ref (fst topleft)
and maxy = ref (snd topleft)
in
let rec calc_bbox = function
| [] -> int_of_float (ceil (!minx +. w')),
int_of_float (ceil (!miny +. w')),
int_of_float (floor (!maxx -. w')),
int_of_float (floor (!maxy -. w'))
| (x,y)::xs ->
if !minx > x then minx := x
else if !maxx < x then maxx := x;
if !miny > y then miny := y
else if !maxy < y then maxy := y;
calc_bbox xs
in
calc_bbox [topright; bottomleft; bottomright]
in
let nw = maxx - minx + 1
and nh = maxy - miny + 1 in
let scale = smooth + 1 in
let weight = scale * scale in
let dst = create (nw * scale) (nh * scale) in
for y = 0 to nh - 1 do
for x = 0 to nw - 1 do
let sr = ref 0
and sg = ref 0
and sb = ref 0
in
for yy = 0 to scale - 1 do
for xx = 0 to scale - 1 do
let sx = float x -. 0.5 +. (float xx +. 0.5) /. float scale in
let sy = float y -. 0.5 +. (float yy +. 0.5) /. float scale in
let ox, oy = proj' sx sy in
let oxi = int_of_float (ox +. 0.5)
and oyi = int_of_float (oy +. 0.5)
in
let c =
try
get img oxi oyi
with
| Image.Out_of_image -> fill
in
sr := !sr + c.r;
sg := !sg + c.g;
sb := !sb + c.b;
done
done;
unsafe_set dst x y {
r = !sr / weight;
g = !sb / weight;
b = !sg / weight;
}
done
done;
dst
*)letto_rgba32t=letrgba32=Rgba32.createt.widtht.heightinfory=0tot.height-1doforx=0tot.width-1doRgba32.unsafe_setrgba32xy{color=unsafe_gettxy;alpha=255;}donedone;rgba32letof_rgba32t=letrgb24=createt.Rgba32.widtht.Rgba32.heightinfory=0tot.Rgba32.height-1doforx=0tot.Rgba32.width-1dolet{color=c}=Rgba32.unsafe_gettxyinunsafe_setrgb24xycdonedone;rgb24