Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
244 chris 1
{
2
	ulong* aDestBits = GetBits();
3
 
4
	int aSrcRowWidth = aSrcMemoryImage->GetWidth();
5
 
6
	int aSrcXI = (int) floor(theSrcRect.mX);
7
	int aSrcYI = (int) floor(theSrcRect.mY);
8
	int aSrcWidthI = (int) ceil(theSrcRect.mWidth + (theSrcRect.mX - aSrcXI));
9
	int aSrcHeightI = (int) ceil(theSrcRect.mHeight + (theSrcRect.mY - aSrcYI));
10
 
11
	if (aSrcXI<0) aSrcXI = 0;
12
	if (aSrcYI<0) aSrcYI = 0;
13
	if (aSrcXI + aSrcWidthI > theImage->mWidth) aSrcWidthI = theImage->mWidth - aSrcXI;
14
	if (aSrcYI + aSrcHeightI > theImage->mHeight) aSrcHeightI = theImage->mHeight - aSrcYI;
15
	if (aSrcWidthI<=0 || aSrcHeightI<=0)
16
		return;
17
 
18
	int aTempDestWidth = theDestRect.mWidth+4;
19
	int aTempDestHeight = theDestRect.mHeight+4;
20
 
21
	// For holding horizontally resized pixels not vertically (yet)
22
	ulong* aNewHorzPixels = new ulong[aTempDestWidth*aSrcHeightI*4];
23
 
24
	ulong* aNewHorzPixelsEnd = aNewHorzPixels + (aTempDestWidth*aSrcHeightI*4);
25
 
26
	ZeroMemory(aNewHorzPixels, aTempDestWidth*aSrcHeightI*4*4);
27
 
28
	int aSrcImageWidth = theImage->GetWidth();
29
 
30
	if (theSrcRect.mWidth >= theDestRect.mWidth)
31
	{
32
		double aDestXFactor = theDestRect.mWidth / theSrcRect.mWidth;
33
		double aDestXOffset = 1.0 + (aSrcXI - theSrcRect.mX) * aDestXFactor;
34
 
35
		// Shrinking
36
 
37
		for (int aSrcX = 0; aSrcX < aSrcWidthI; aSrcX++)
38
		{
39
			double aDestX1 = aDestXFactor * aSrcX + aDestXOffset;
40
			double aDestX2 = aDestX1 + aDestXFactor;
41
 
42
			int aDestXI1 = (int) aDestX1;
43
			int aDestXI2 = (int) aDestX2;
44
 
45
			SRC_TYPE* s1 = &aSrcBits[aSrcYI*aSrcRowWidth + aSrcXI+aSrcX];
46
 
47
			if (aDestXI1 == aDestXI2)
48
			{
49
				ulong* d = &aNewHorzPixels[aDestXI1*4];
50
				int aFactor = (int) (257 * aDestXFactor);
51
 
52
				for (int aSrcY = 0; aSrcY < aSrcHeightI; aSrcY++)
53
				{
54
					ulong pixel = READ_COLOR(s1);
55
 
56
					*d++ += aFactor * ((pixel      ) & 0xFF);
57
					*d++ += aFactor * ((pixel >>  8) & 0xFF);
58
					*d++ += aFactor * ((pixel >> 16) & 0xFF);
59
					*d++ += aFactor * ((pixel >> 24) & 0xFF);
60
 
61
					DBG_ASSERTE(d <= aNewHorzPixelsEnd);
62
 
63
					d += aTempDestWidth*4 - 4;
64
					s1 += aSrcRowWidth;
65
				}
66
			}
67
			else
68
			{
69
				int aFactor1 = (int) (257 * (aDestXI2 - aDestX1));
70
				int aFactor2 = (int) (257 * (aDestX2 - aDestXI2));
71
 
72
				ulong* d = &aNewHorzPixels[aDestXI1*4];
73
 
74
				for (int aSrcY = 0; aSrcY < aSrcHeightI; aSrcY++)
75
				{
76
					ulong pixel = READ_COLOR(s1);
77
 
78
					*d++ += aFactor1 * ((pixel      ) & 0xFF);
79
					*d++ += aFactor1 * ((pixel >>  8) & 0xFF);
80
					*d++ += aFactor1 * ((pixel >> 16) & 0xFF);
81
					*d++ += aFactor1 * ((pixel >> 24) & 0xFF);
82
 
83
					*d++ += aFactor2 * ((pixel      ) & 0xFF);
84
					*d++ += aFactor2 * ((pixel >>  8) & 0xFF);
85
					*d++ += aFactor2 * ((pixel >> 16) & 0xFF);
86
					*d++ += aFactor2 * ((pixel >> 24) & 0xFF);
87
 
88
					DBG_ASSERTE(d <= aNewHorzPixelsEnd);
89
 
90
					d += aTempDestWidth*4 - 8;
91
					s1 += aSrcRowWidth;
92
				}
93
			}
94
		}
95
	}
96
	else
97
	{
98
		double aSrcXFactor;
99
		if (theDestRect.mWidth != 1)
100
			aSrcXFactor = (theSrcRect.mWidth - 1) / (theDestRect.mWidth - 1);
101
		else
102
			aSrcXFactor = (theSrcRect.mWidth) / (theDestRect.mWidth);
103
 
104
		for (int aDestX = 1; aDestX < aTempDestWidth-1; aDestX++)
105
		{
106
			ulong* d = &aNewHorzPixels[aDestX*4];
107
 
108
			double aSrcX = (aDestX - 1)*aSrcXFactor + theSrcRect.mX;
109
			int aSrcXI = (int) aSrcX;
110
 
111
			int aFactor1 = (int) (257 * (1.0 - (aSrcX - aSrcXI)));
112
			int aFactor2 = (int) (257 - aFactor1);
113
 
114
			SRC_TYPE* s = &aSrcBits[aSrcYI*aSrcRowWidth+aSrcXI];
115
 
116
			for (int aDestY = 0; aDestY < aSrcHeightI; aDestY++)
117
			{
118
				ulong pixel1 = READ_COLOR(s++);
119
				ulong pixel2 = READ_COLOR(s);
120
 
121
				*d++ = (aFactor1 * ((pixel1      ) & 0xFF)) + (aFactor2 * ((pixel2      ) & 0xFF));
122
				*d++ = (aFactor1 * ((pixel1 >>  8) & 0xFF)) + (aFactor2 * ((pixel2 >>  8) & 0xFF));
123
				*d++ = (aFactor1 * ((pixel1 >> 16) & 0xFF)) + (aFactor2 * ((pixel2 >> 16) & 0xFF));
124
				*d++ = (aFactor1 * ((pixel1 >> 24) & 0xFF)) + (aFactor2 * ((pixel2 >> 24) & 0xFF));
125
 
126
				DBG_ASSERTE(d <= aNewHorzPixelsEnd);
127
 
128
				d += aTempDestWidth*4 - 4;
129
				s += aSrcRowWidth - 1;
130
			}
131
		}
132
	}
133
 
134
	ulong* aNewPixels = new ulong[aTempDestWidth*aTempDestHeight*4];
135
 
136
	ulong* aNewPixelsEnd = aNewPixels + (aTempDestWidth*aTempDestHeight*4);
137
 
138
	ZeroMemory(aNewPixels, aTempDestWidth*aTempDestHeight*4*4);
139
 
140
	// Now resize vertically
141
	if (theSrcRect.mHeight >= theDestRect.mHeight)
142
	{
143
		double aDestYFactor = theDestRect.mHeight / theSrcRect.mHeight;
144
 
145
		double aDestYOffset = 1.0 + (aSrcYI - theSrcRect.mY) * aDestYFactor;
146
 
147
		for (int aSrcY = 0; aSrcY < aSrcHeightI; aSrcY++)
148
		{
149
			double aDestY1 = aDestYFactor * aSrcY + aDestYOffset;
150
			double aDestY2 = aDestY1 + aDestYFactor;
151
 
152
			int aDestYI1 = (int) floor(aDestY1);
153
			int aDestYI2 = (int) floor(aDestY2);
154
 
155
			ulong* s = &aNewHorzPixels[aSrcY*aTempDestWidth*4];
156
 
157
			if (aDestYI1 == aDestYI2)
158
			{
159
				ulong* d = &aNewPixels[aDestYI1*aTempDestWidth*4];
160
				int aFactor = (int) (256 * aDestYFactor);
161
 
162
				for (int aSrcX = 0; aSrcX < aTempDestWidth; aSrcX++)
163
				{
164
					*d++ += aFactor * *s++;
165
					*d++ += aFactor * *s++;
166
					*d++ += aFactor * *s++;
167
					*d++ += aFactor * *s++;
168
				}
169
 
170
				DBG_ASSERTE(d <= aNewPixelsEnd);
171
			}
172
			else
173
			{
174
				int aFactor1 = (int) (256 * (aDestYI2 - aDestY1));
175
				int aFactor2 = (int) (256 * (aDestY2 - aDestYI2));
176
 
177
				ulong* d1 = &aNewPixels[aDestYI1*aTempDestWidth*4];
178
				ulong* d2 = &aNewPixels[aDestYI2*aTempDestWidth*4];
179
 
180
				for (int aSrcX = 0; aSrcX < aTempDestWidth; aSrcX++)
181
				{
182
					*d1++ += aFactor1 * *s;
183
					*d2++ += aFactor2 * *s++;
184
 
185
					*d1++ += aFactor1 * *s;
186
					*d2++ += aFactor2 * *s++;
187
 
188
					*d1++ += aFactor1 * *s;
189
					*d2++ += aFactor2 * *s++;
190
 
191
					*d1++ += aFactor1 * *s;
192
					*d2++ += aFactor2 * *s++;
193
				}
194
 
195
				DBG_ASSERTE(d1 <= aNewPixelsEnd);
196
				DBG_ASSERTE(d2 <= aNewPixelsEnd);
197
			}
198
		}
199
	}
200
	else
201
	{
202
		double aSrcYFactor;
203
		if (theDestRect.mHeight != 1)
204
			aSrcYFactor = (theSrcRect.mHeight - 1) / (theDestRect.mHeight - 1);
205
		else
206
			aSrcYFactor = (theSrcRect.mHeight) / (theDestRect.mHeight);
207
 
208
		for (int aDestY = 1; aDestY < theDestRect.mHeight + 1; aDestY++)
209
		{
210
			ulong* d = &aNewPixels[(aDestY*aTempDestWidth+1)*4];
211
 
212
			double aSrcY = (aDestY-1)*aSrcYFactor + (theSrcRect.mY - ((int) theSrcRect.mY));
213
			int aSrcYI = (int) aSrcY;
214
 
215
			int aFactor1 = (int) (256 * (1.0 - (aSrcY - aSrcYI)));
216
			int aFactor2 = 256 - aFactor1;
217
 
218
			ulong* s1 = &aNewHorzPixels[(aSrcYI*aTempDestWidth+1)*4];
219
			ulong* s2;
220
 
221
			if (aSrcYI == aSrcHeightI - 1)
222
				s2 = s1;
223
			else
224
				s2 = &aNewHorzPixels[((aSrcYI+1)*aTempDestWidth+1)*4];
225
 
226
			for (int aDestX = 1; aDestX < aTempDestWidth-1; aDestX++)
227
			{
228
				*d++ = (aFactor1 * *s1++) + (aFactor2 * *s2++);
229
				*d++ = (aFactor1 * *s1++) + (aFactor2 * *s2++);
230
				*d++ = (aFactor1 * *s1++) + (aFactor2 * *s2++);
231
				*d++ = (aFactor1 * *s1++) + (aFactor2 * *s2++);
232
			}
233
		}
234
	}
235
 
236
 
237
	for (int y = 0; y < theDestRect.mHeight; y++)
238
	{
239
		ulong* aDestPixels = &aDestBits[(theDestRect.mY+y)*mWidth+theDestRect.mX];
240
 
241
		for (int x = 0; x < theDestRect.mWidth; x++)
242
		{
243
			ulong *p = &aNewPixels[((y+1)*aTempDestWidth+x+1)*4];
244
 
245
			int b = (*p++) >> 16;
246
			int g = (*p++) >> 16;
247
			int r = (*p++) >> 16;
248
			int a = (*p++) >> 16;
249
 
250
			/*aDestBits[(theDestRect.mY+y)*mWidth+theDestRect.mX+x] =
251
				(r) | (g << 8) | (b << 16) | (a << 24);*/
252
 
253
			if (a != 0)
254
			{
255
				ulong dest = *aDestPixels;
256
				int aDestAlpha = dest >> 24;
257
				int aNewDestAlpha = aDestAlpha + ((255 - aDestAlpha) * a) / 255;
258
 
259
				//a = 255 * a / (a + aDestAlpha);
260
				int oma = 256 - a;
261
 
262
				DBG_ASSERTE(aDestPixels < aDestEnd);
263
 
264
				*(aDestPixels++) = (aNewDestAlpha << 24) |
265
					(((((dest & 0x0000FF) * oma) >> 8) & 0x0000FF) + (((b * a) >> 8))) |
266
					(((((dest & 0x00FF00) * oma) >> 8) & 0x00FF00) + (((g * a) >> 8) << 8)) |
267
					(((((dest & 0xFF0000) * oma) >> 8) & 0xFF0000) + (((r * a) >> 8) << 16));
268
			}
269
			else
270
				aDestPixels++;
271
		}
272
	}
273
 
274
	delete[] aNewPixels;
275
	delete[] aNewHorzPixels;
276
}