Subversion Repositories forest

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 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.