Subversion Repositories forest

Rev

Blame | Last modification | View Log | RSS feed

  1. library Resize32;
  2.  
  3. {$R *.res}
  4.  
  5. type
  6.   TImgMemBlockHeader = packed record
  7.     width: cardinal;
  8.     height: cardinal;
  9.     colordepth: cardinal;
  10.   end;
  11.   PImgMemBlockHeader = ^TImgMemBlockHeader;
  12.  
  13. function _Resize24(srcMemblock, dstMemblock: PImgMemBlockHeader; newWidth, newHeight: Cardinal): integer;
  14. // --- Based on http://www.davdata.nl/math/bmresize.html ---
  15. type
  16.   TBGRATriple = packed record
  17.     B: byte;
  18.     G: byte;
  19.     R: byte;
  20.   end;
  21.   PBGRATriple = ^TBGRATriple;
  22. var
  23.   psStep,pdStep: integer;
  24.   ps0,pd0 : Pointer;       //scanline[0], row steps
  25.   sx1,sy1,sx2,sy2 : single;             //source field positions
  26.   x,y,i,j: word;  //source,dest field pixels
  27.   destR,destG,destB : single;           //destination colors
  28.   src: TBGRATriple;                      //source colors
  29.   fx,fy,fix,fiy,dyf : single;           //factors
  30.   fxstep,fystep, dx,dy : single;
  31.   psi,psj : Pointer;
  32.   AP : single;
  33.   istart,iend,jstart,jend : word;
  34.   devX1,devX2,devY1,devY2 : single;
  35.   DSTPIX: PBGRATriple;
  36. begin
  37.   dstMemblock.width := newWidth;
  38.   dstMemblock.height := newHeight;
  39.   dstMemblock.colordepth := sizeof(TBGRATriple) * 8;
  40.  
  41.   if srcMemblock.colordepth <> dstMemblock.colordepth then
  42.   begin
  43.     result := -1;
  44.     exit;
  45.   end;
  46.  
  47.   result := 0;
  48.  
  49.   ps0 := Pointer(srcMemblock); Inc(pbyte(ps0), SizeOf(TImgMemBlockHeader));
  50.   psstep := -srcMemblock.width * sizeof(TBGRATriple);
  51.   pd0 := Pointer(dstMemblock); Inc(pbyte(pd0), SizeOf(TImgMemBlockHeader));
  52.   pdstep := -dstMemblock.width * sizeof(TBGRATriple);
  53.   fx := srcMemblock.width/ newWidth;
  54.   fy := srcMemblock.height/newHeight;
  55.   fix := 1/fx;
  56.   fiy := 1/fy;
  57.   fxstep := 0.9999 * fx;
  58.   fystep := 0.9999 * fy;
  59.   DSTPIX := PBGRATriple(pd0);
  60.   for y := 0 to newHeight-1 do         //vertical destination pixels
  61.   begin
  62.     sy1 := fy * y;
  63.     sy2 := sy1 + fystep;
  64.     jstart := trunc(sy1);
  65.     jend := trunc(sy2);
  66.     devY1 := 1-sy1+jstart;
  67.     devY2 := jend+1-sy2;
  68.     for x := 0 to newWidth-1 do        //horizontal destination pixels
  69.     begin
  70.       sx1 := fx * x;                        //x related values are repeated
  71.       sx2 := sx1 + fxstep;                  //for each y and may be placed in
  72.       istart := trunc(sx1);                 //lookup table
  73.       iend := trunc(sx2);                   //...
  74.  
  75.       if istart >= srcMemblock.width then istart := srcMemblock.width-1;
  76.       if iend   >= srcMemblock.width then iend   := srcMemblock.width-1;
  77.  
  78.       devX1 := 1-sx1+istart;                  //...
  79.       devX2 := iend+1-sx2;                  //...
  80.       destR := 0; destG := 0; destB := 0;   //clear destination colors
  81.  
  82.       if jstart >= srcMemblock.height then jstart := srcMemblock.height-1;
  83.       if jend   >= srcMemblock.height then jend   := srcMemblock.height-1;
  84.  
  85.       psj := ps0; dec(pbyte(psj), jstart*psStep);
  86.       dy := devY1;
  87.  
  88.       for j := jstart to jend do  //vertical source pixels
  89.       begin
  90.         if j = jend then dy := dy - devY2;
  91.         dyf := dy*fiy;
  92.         psi := psj; Inc(pbyte(psi), istart*SizeOf(TBGRATriple));
  93.         dx := devX1;
  94.         for i := istart to iend do //horizontal source pixels
  95.         begin
  96.           if i = iend then dx := dx - devX2;
  97.           AP := dx*dyf*fix;
  98.           src := PBGRATriple(psi)^;
  99.  
  100.           destB := destB + src.B*AP;
  101.           destG := destG + src.G*AP;
  102.           destR := destR + src.R*AP;
  103.  
  104.           inc(pbyte(psi), sizeof(TBGRATriple));
  105.           dx := 1;
  106.         end;//for i
  107.         dec(pbyte(psj),psStep);
  108.         dy := 1;
  109.       end;//for j
  110.  
  111.       src.B := round(destB);
  112.       src.G := round(destG);
  113.       src.R := round(destR);
  114.       DSTPIX^ := src;
  115.       inc(DSTPIX, 1{element});
  116.       inc(result, SizeOf(TBGRATriple));
  117.     end;//for x
  118.   end;//for y
  119. end;
  120.  
  121. function _Resize32(srcMemblock, dstMemblock: PImgMemBlockHeader; newWidth, newHeight: Cardinal): integer;
  122. // --- Based on http://www.davdata.nl/math/bmresize.html ---
  123. type
  124.   TBGRATriple = packed record
  125.     B: byte;
  126.     G: byte;
  127.     R: byte;
  128.     A: byte;
  129.   end;
  130.   PBGRATriple = ^TBGRATriple;
  131. var
  132.   psStep,pdStep: integer;
  133.   ps0,pd0 : Pointer;       //scanline[0], row steps
  134.   sx1,sy1,sx2,sy2 : single;             //source field positions
  135.   x,y,i,j: word;  //source,dest field pixels
  136.   destA,destR,destG,destB : single;           //destination colors
  137.   src: TBGRATriple;                      //source colors
  138.   fx,fy,fix,fiy,dyf : single;           //factors
  139.   fxstep,fystep, dx,dy : single;
  140.   psi,psj : Pointer;
  141.   AP : single;
  142.   istart,iend,jstart,jend : word;
  143.   devX1,devX2,devY1,devY2 : single;
  144.   DSTPIX: PBGRATriple;
  145. begin
  146.   dstMemblock.width := newWidth;
  147.   dstMemblock.height := newHeight;
  148.   dstMemblock.colordepth := sizeof(TBGRATriple) * 8;
  149.  
  150.   if srcMemblock.colordepth <> dstMemblock.colordepth then
  151.   begin
  152.     result := -1;
  153.     exit;
  154.   end;
  155.  
  156.   result := 0;
  157.  
  158.   ps0 := Pointer(srcMemblock); Inc(pbyte(ps0), SizeOf(TImgMemBlockHeader));
  159.   psstep := -srcMemblock.width * sizeof(TBGRATriple);
  160.   pd0 := Pointer(dstMemblock); Inc(pbyte(pd0), SizeOf(TImgMemBlockHeader));
  161.   pdstep := -dstMemblock.width * sizeof(TBGRATriple);
  162.   fx := srcMemblock.width/ newWidth;
  163.   fy := srcMemblock.height/newHeight;
  164.   fix := 1/fx;
  165.   fiy := 1/fy;
  166.   fxstep := 0.9999 * fx;
  167.   fystep := 0.9999 * fy;
  168.   DSTPIX := PBGRATriple(pd0);
  169.   for y := 0 to newHeight-1 do         //vertical destination pixels
  170.   begin
  171.     sy1 := fy * y;
  172.     sy2 := sy1 + fystep;
  173.     jstart := trunc(sy1);
  174.     jend := trunc(sy2);
  175.     devY1 := 1-sy1+jstart;
  176.     devY2 := jend+1-sy2;
  177.     for x := 0 to newWidth-1 do        //horizontal destination pixels
  178.     begin
  179.       sx1 := fx * x;                        //x related values are repeated
  180.       sx2 := sx1 + fxstep;                  //for each y and may be placed in
  181.       istart := trunc(sx1);                 //lookup table
  182.       iend := trunc(sx2);                   //...
  183.  
  184.       if istart >= srcMemblock.width then istart := srcMemblock.width-1;
  185.       if iend   >= srcMemblock.width then iend   := srcMemblock.width-1;
  186.  
  187.       devX1 := 1-sx1+istart;                  //...
  188.       devX2 := iend+1-sx2;                  //...
  189.       destR := 0; destG := 0; destB := 0; destA := 0;   //clear destination colors
  190.  
  191.       if jstart >= srcMemblock.height then jstart := srcMemblock.height-1;
  192.       if jend   >= srcMemblock.height then jend   := srcMemblock.height-1;
  193.  
  194.       psj := ps0; dec(pbyte(psj), jstart*psStep);
  195.       dy := devY1;
  196.  
  197.       for j := jstart to jend do  //vertical source pixels
  198.       begin
  199.         if j = jend then dy := dy - devY2;
  200.         dyf := dy*fiy;
  201.         psi := psj; Inc(pbyte(psi), istart*SizeOf(TBGRATriple));
  202.         dx := devX1;
  203.         for i := istart to iend do //horizontal source pixels
  204.         begin
  205.           if i = iend then dx := dx - devX2;
  206.           AP := dx*dyf*fix;
  207.           src := PBGRATriple(psi)^;
  208.  
  209.           destB := destB + src.B*AP;
  210.           destG := destG + src.G*AP;
  211.           destR := destR + src.R*AP;
  212.           destA := destA + src.A*AP;
  213.  
  214.           inc(pbyte(psi), sizeof(TBGRATriple));
  215.           dx := 1;
  216.         end;//for i
  217.         dec(pbyte(psj),psStep);
  218.         dy := 1;
  219.       end;//for j
  220.  
  221.       src.B := round(destB);
  222.       src.G := round(destG);
  223.       src.R := round(destR);
  224.       src.A := round(destA);
  225.       DSTPIX^ := src;
  226.       inc(DSTPIX, 1{element});
  227.       inc(result, SizeOf(TBGRATriple));
  228.     end;//for x
  229.   end;//for y
  230. end;
  231.  
  232. function DestSize(memblock: PImgMemBlockHeader; newWidth, newHeight: Cardinal): integer; cdecl;
  233. begin
  234.   if memblock.colordepth = 32 then
  235.     result := SizeOf(TImgMemBlockHeader) + newWidth * newHeight * 4
  236.   else if memblock.colordepth = 24 then
  237.     result := SizeOf(TImgMemBlockHeader) + newWidth * newHeight * 3
  238.   else
  239.     result := -1;
  240. end;
  241.  
  242. function Resize(srcMemblock, dstMemblock: PImgMemBlockHeader; newWidth, newHeight: Cardinal): integer; cdecl;
  243. begin
  244.   if srcMemblock.colordepth = 32 then
  245.     result := _Resize32(srcMemblock, dstMemblock, newWidth, newHeight)
  246.   else if srcMemblock.colordepth = 24 then
  247.     result := _Resize24(srcMemblock, dstMemblock, newWidth, newHeight)
  248.   else
  249.     result := -1;
  250. end;
  251.  
  252. exports
  253.   Resize name 'Resize',
  254.   DestSize name 'DestSize';
  255.  
  256. end.
  257.