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. |