const stepsize =64;
procedure tbwimagegen<T>.rotatealign(Target:TLocalType);
// warning: this method has some fixes that hardcode it to RGB24 to avoid delphi XE bugs.
// (multiplications by 3)
var stepsx,stepsy,restx,resty : Integer;
RowPitchSource, RowPitchTarget : Integer;
pSource, pTarget,ps1,ps2 : RefT;
x,y,i,j: integer;
rpstep : integer;
begin
RowPitchSource := RowPitch; // bytes to jump to next line. Can be negative (includes alignment)
RowPitchTarget := target.RowPitch; rpstep:=RowPitchTarget*stepsize;
stepsx:=ImageWidth div stepsize;
stepsy:=ImageHeight div stepsize;
// check if mod 16=0 here for both dimensions, if so -> SSE2?
for y := 0 to stepsy- 1 do
begin
psource:=GetImagePointer(0,y*stepsize); // gets pointer to pixel x,y
ptarget:=Target.GetImagePointer(target.imagewidth-(y+1)*stepsize,0);
for x := 0 to stepsx - 1 do
begin
for i := 0 to stepsize - 1 do
begin
ps1:=reft(@pbbyte(psource)[rowpitchsource*i]); // ( 0,i)
ps2:=reft(@ptarget[(stepsize-1-i)]); // (maxx-i,0);
for j := 0 to stepsize - 1 do
begin
ps2[0]:=ps1[workaround*j];
ps2:=reft(@pbyte(ps2)[RowPitchTarget]);
// inc(pbyte(ps2),RowPitchTarget);
end;
end;
inc(psource,stepsize);
// inc(pbyte(ptarget),rpstep);
ptarget:=@pbyte(ptarget)[rpstep];
end;
end;
// 3 more areas to do, with dimensions
// - stepsy*stepsize * restx // right most column of restx width
// - stepsx*stepsize * resty // bottom row with resty height
// - restx*resty // bottom-right rectangle.
restx:=ImageWidth mod stepsize; // typically zero because width is typically 1024 or 2048
resty:=Imageheight mod stepsize;
if restx>0 then
begin
// one loop less, since we know this fits in one line of "blocks"
psource:=GetImagePointer(ImageWidth-restx,0); // gets pointer to pixel x,y
ptarget:=Target.GetImagePointer(Target.imagewidth-stepsize,Target.imageheight-restx);
for y := 0 to stepsy - 1 do
begin
for i := 0 to stepsize - 1 do
begin
ps1:=@pbyte(psource)[rowpitchsource*i]; // ( 0,i)
ps2:=@ptarget[stepsize-1-i]; // (maxx-i,0);
for j := 0 to restx - 1 do
begin
ps2[0]:=ps1[j];
inc(pbyte(ps2),RowPitchTarget);
end;
end;
inc(pbyte(psource),stepsize*RowPitchSource);
dec(ptarget,stepsize);
end;
end;
if resty>0 then
begin
// one loop less, since we know this fits in one line of "blocks"
psource:=GetImagePointer(0,ImageHeight-resty); // gets pointer to pixel x,y
ptarget:=Target.GetImagePointer(0,0);
for x := 0 to stepsx - 1 do
begin
for i := 0 to resty- 1 do
begin
ps1:=@pbyte(psource)[rowpitchsource*i]; // ( 0,i)
ps2:=@ptarget[resty-1-i]; // (maxx-i,0);
for j := 0 to stepsize - 1 do
begin
ps2[0]:=ps1[j];
inc(pbyte(ps2),RowPitchTarget);
end;
end;
inc(psource,stepsize);
inc(pbyte(ptarget),rpstep);
end;
end;
if (resty>0) and (restx>0) then
begin
// one loop less, since we know this fits in one line of "blocks"
psource:=GetImagePointer(ImageWidth-restx,ImageHeight-resty); // gets pointer to pixel x,y
ptarget:=Target.GetImagePointer(0,target.ImageHeight-restx);
for i := 0 to resty- 1 do
begin
ps1:=@pbyte(psource)[rowpitchsource*i]; // ( 0,i)
ps2:=@ptarget[resty-1-i]; // (maxx-i,0);
for j := 0 to restx - 1 do
begin
ps2[0]:=ps1[j];
inc(pbyte(ps2),RowPitchTarget);
end;
end;
end;
end;
Bookmarks