Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/CPixelbitStamp.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Sun Aug 15 01:53:13 2010 UTC (13 years, 9 months ago) by okadu
File MIME type: text/x-c++src
File size: 10897 byte(s)


1 #include "CPixelbit.h"
2
3 // 関数宣言
4 void Dialog(char *, ...);
5
6 #ifdef ENABLE_RECT_BOUNDARY
7
8 /*
9 * 描画制限領域の初期化
10 */
11 void CPixelbit::ResetBoundary(){
12 m_BoundLeft = m_BoundTop = 0;
13 m_BoundRight = m_Width;
14 m_BoundBottom = m_Height;
15 }
16
17 /*
18 * 描画制限領域の設定
19 */
20 void CPixelbit::SetBoundary(
21 int x, int y, // 座標
22 int w, int h // サイズ
23 ){
24 m_BoundLeft = x;
25 m_BoundTop = y;
26 m_BoundRight = x+w;
27 m_BoundBottom = y+h;
28 if(m_BoundLeft<0) m_BoundLeft = 0;
29 if(m_BoundTop<0) m_BoundTop = 0;
30 if(m_BoundRight>m_Width) m_BoundRight = m_Width;
31 if(m_BoundBottom>m_Height) m_BoundBottom = m_Height;
32 }
33
34 #endif // ENABLE_RECT_BOUNDARY
35
36 /*
37 * アルファチャネルを指定値でリセット
38 */
39 void CPixelbit::ResetAlphaChannel(
40 BYTE alpha // アルファ値
41 ){
42 int i;
43 for(i = 0; i<m_Height; i++){
44 PDWORD line = m_PixelAdr+m_Width*i, stop = line+m_Width;
45 for(; line<stop; line++) *((PBYTE)line+3) = alpha;
46 }
47 }
48
49 /*
50 * コピー時の矩形範囲を画像内に補正
51 *
52 * 戻り値: コピー範囲があれば TRUE を返す
53 */
54 BOOL CPixelbit::FixLocation(
55 CPixelbit *dest, // コピー先画像
56 int *dx, int *dy, // コピー先座標
57 int *sx, int *sy, // コピー元座標
58 int *w, int *h // コピーサイズ
59 ){
60 #ifdef ENABLE_RECT_BOUNDARY
61 #define BOUNDLEFT dest->m_BoundLeft
62 #define BOUNDTOP dest->m_BoundTop
63 #else
64 #define BOUNDLEFT 0
65 #define BOUNDTOP 0
66 #endif
67 if(*dx<=BOUNDLEFT-m_Width || *dy<=BOUNDTOP-m_Height
68 || *dx>=dest->m_BoundRight || *dy>=dest->m_BoundBottom) return FALSE;
69 int delta;
70 if((delta = BOUNDLEFT-*dx)>0){
71 *w -= delta; *sx += delta;
72 *dx = BOUNDLEFT;
73 }
74 if((delta = BOUNDTOP-*dy)>0){
75 *h -= delta; *sy += delta;
76 *dy = BOUNDTOP;
77 }
78 if((delta = *dx+*w-dest->m_BoundRight)>0) *w -= delta;
79 if((delta = *dy+*h-dest->m_BoundBottom)>0) *h -= delta;
80 return *w>0 && *h>0;
81 }
82
83 /*
84 * 指定デバイスコンテキストに描画
85 *
86 * 戻り値: 成功したら TRUE を返す
87 */
88 BOOL CPixelbit::WindowStamp(
89 HDC hdc, // デバイスコンテキスト
90 int dx, int dy, // コピー先座標
91 int sx, int sy, // コピー元座標
92 int w, int h // コピーサイズ
93 ){
94 return m_ColorKey==0xffffffff ? SetDIBitsToDevice(hdc, dx, dy, w, h,
95 sx, m_Height-sy-h, 0, m_Height, m_PixelAdr, &m_BmpInfo, DIB_RGB_COLORS)
96 : ms_TransBlt(hdc, dx, dy, w, h, GetHDC(), sx, sy, w, h, m_ColorKey);
97 }
98
99 /*
100 * 矩形範囲のコピー
101 *
102 * 戻り値: 成功したら TRUE を返す
103 */
104 BOOL CPixelbit::PlainStamp(
105 CPixelbit *dest, // コピー先画像
106 int dx, int dy, // コピー先座標
107 int sx, int sy, // コピー元座標
108 int w, int h // コピーサイズ
109 ){
110 if(!FixLocation(dest, &dx, &dy, &sx, &sy, &w, &h)) return FALSE;
111 return m_ColorKey==0xffffffff ? SetDIBitsToDevice(dest->m_BmpHdc, dx, dy, w, h,
112 sx, m_Height-sy-h, 0, m_Height, m_PixelAdr, &m_BmpInfo, DIB_RGB_COLORS)
113 : ms_TransBlt(dest->m_BmpHdc, dx, dy, w, h, GetHDC(), sx, sy, w, h, m_ColorKey);
114 }
115
116 /*
117 * 矩形範囲のコピー
118 *
119 * 戻り値: 成功したら TRUE を返す
120 */
121 BOOL CPixelbit::PlainStamp32(
122 CPixelbit *dest, // コピー先画像
123 int dx, int dy, // コピー先座標
124 int sx, int sy, // コピー元座標
125 int w, int h // コピーサイズ
126 ){
127 int i;
128 if(!FixLocation(dest, &dx, &dy, &sx, &sy, &w, &h)) return FALSE;
129 for(i = 0; i<h; i++){
130 PDWORD line1 = m_PixelAdr+m_Width*(i+sy)+sx, stop = line1+w;
131 PDWORD line2 = dest->m_PixelAdr+dest->m_Width*(i+dy)+dx;
132 while(line1<stop) *line2++ = *line1++;
133 }
134 return TRUE;
135 }
136
137 /*
138 * アルファブレンドコピー
139 *
140 * 戻り値: 成功したら TRUE を返す
141 */
142 BOOL CPixelbit::AlphaBlendStamp(
143 CPixelbit *dest, // コピー先画像
144 int dx, int dy, // コピー先座標
145 int sx, int sy, // コピー元座標
146 int w, int h // コピーサイズ
147 ){
148 int i;
149 if(!FixLocation(dest, &dx, &dy, &sx, &sy, &w, &h)) return FALSE;
150 for(i = 0; i<h; i++){
151 PDWORD line1 = m_PixelAdr+m_Width*(i+sy)+sx, stop = line1+w;
152 PDWORD line2 = dest->m_PixelAdr+dest->m_Width*(i+dy)+dx;
153 while(line1<stop){
154 int alpha, r1, g1, b1, r2, g2, b2;
155 SplitColorA(*line1, &alpha, &r1, &g1, &b1);
156 SplitColor(*line2, &r2, &g2, &b2);
157 int beta = 255-alpha;
158 PBYTE c = (PBYTE)line2;
159 *c = (b1*alpha+b2*beta)/255; c++;
160 *c = (g1*alpha+g2*beta)/255; c++;
161 *c = (r1*alpha+r2*beta)/255;
162 line1++; line2++;
163 }
164 }
165 return TRUE;
166 }
167
168 /*
169 * 伸縮コピー
170 *
171 * 戻り値: 成功したら TRUE を返す
172 */
173 BOOL CPixelbit::StretchStamp(
174 CPixelbit *dest, // コピー先画像
175 int dx, int dy, // コピー先座標
176 int dw, int dh, // コピー先サイズ
177 int sx, int sy, // コピー元座標
178 int sw, int sh, // コピー元サイズ
179 int halftone // 伸縮モード
180 ){
181 SetStretchBltMode(dest->m_BmpHdc, halftone ? HALFTONE : COLORONCOLOR);
182 return StretchBlt(dest->m_BmpHdc, dx, dy, dw, dh, m_BmpHdc, sx, sy, sw, sh, SRCCOPY);
183 }
184
185 /*
186 * バイリニア伸縮コピー (範囲チェックなし)
187 *
188 * 戻り値: 成功したら TRUE を返す
189 */
190 BOOL CPixelbit::BilinearStamp(
191 CPixelbit *dest, // コピー先画像
192 int dx, int dy, // コピー先座標
193 int dw, int dh, // コピー先サイズ
194 int sx, int sy, // コピー元座標
195 int sw, int sh // コピー元サイズ
196 ){
197 if(dw==sw && dh==sh) return PlainStamp(dest, dx, dy, sx, sy, sw, sh);
198 bool first = true;
199 int a1, r1, g1, b1, a2, r2, g2, b2;
200 DWORD x, y, fx, fy, tx, ty, tw, th;
201 CPixelbit temp, *from, *to;
202 if(sw*dh<dw*sh) goto VERTICAL;
203 HORIZONTAL:
204 if(dw!=sw){
205 tw = dw;
206 if(first || dh==sh){
207 from = this; fx = sx; fy = sy;
208 }else{
209 from = &temp; fx = fy = 0;
210 }
211 if(!first || dh==sh){
212 to = dest; tx = dx; ty = dy; th = dh;
213 }else{
214 to = &temp; tx = ty = 0; th = sh;
215 temp.Clear(tw, th);
216 }
217 if(dw<sw){
218 DWORD div = sw/tw, mod = sw%tw;
219 double ratio = (double)tw/sw;
220 for(y = 0; y<th; y++){
221 DWORD alpha = 0;
222 PDWORD line1 = from->m_PixelAdr+from->m_Width*(y+fy)+fx;
223 PBYTE line2 = (PBYTE)(to->m_PixelAdr+to->m_Width*(y+ty)+tx);
224 for(x = 0; x<tw; x++){
225 DWORD i = div, j = mod;
226 double asum = 0.0, rsum = 0.0, gsum = 0.0, bsum = 0.0;
227 if(alpha){
228 double beta = (double)(tw-alpha)/tw;
229 SplitColorA(*line1++, &a1, &r1, &g1, &b1);
230 asum += a1*beta; rsum += r1*beta;
231 gsum += g1*beta; bsum += b1*beta;
232 i--;
233 }
234 do{
235 if(!i){
236 if((alpha += mod)<tw) break;
237 alpha -= tw;
238 }
239 SplitColorA(*line1++, &a1, &r1, &g1, &b1);
240 asum += a1; rsum += r1; gsum += g1; bsum += b1;
241 } while(i--);
242 if(alpha){
243 double beta = (double)alpha/tw;
244 SplitColorA(*line1, &a1, &r1, &g1, &b1);
245 asum += a1*beta; rsum += r1*beta;
246 gsum += g1*beta; bsum += b1*beta;
247 }
248 *line2++ = (BYTE)(ratio*bsum+0.5);
249 *line2++ = (BYTE)(ratio*gsum+0.5);
250 *line2++ = (BYTE)(ratio*rsum+0.5);
251 *line2++ = (BYTE)(ratio*asum+0.5);
252 }
253 }
254 }else{
255 DWORD round = tw/2;
256 for(y = 0; y<th; y++){
257 DWORD alpha = (tw+sw)/2;
258 PDWORD begin = from->m_PixelAdr+from->m_Width*(y+fy)+fx;
259 PDWORD line1 = begin-1, end = line1+sw;
260 PBYTE line2 = (PBYTE)(to->m_PixelAdr+to->m_Width*(y+ty)+tx);
261 for(x = 0; x<tw; x++){
262 SplitColorA(*(line1<begin ? begin : line1), &a1, &r1, &g1, &b1);
263 SplitColorA(*(line1<end ? line1+1 : end), &a2, &r2, &g2, &b2);
264 DWORD beta = tw-alpha;
265 *line2++ = (BYTE)((b1*beta+b2*alpha+round)/tw);
266 *line2++ = (BYTE)((g1*beta+g2*alpha+round)/tw);
267 *line2++ = (BYTE)((r1*beta+r2*alpha+round)/tw);
268 *line2++ = (BYTE)((a1*beta+a2*alpha+round)/tw);
269 if((alpha += sw)>=tw){
270 line1++;
271 alpha -= tw;
272 }
273 }
274 }
275 }
276 }
277 if(!first) return TRUE;
278 first = false;
279 VERTICAL:
280 if(dh!=sh){
281 th = dh;
282 if(first || dw==sw){
283 from = this; fx = sx; fy = sy;
284 }else{
285 from = &temp; fx = fy = 0;
286 }
287 if(!first || dw==sw){
288 to = dest; tx = dx; ty = dy; tw = dw;
289 }else{
290 to = &temp; tx = ty = 0; tw = sw;
291 temp.Clear(tw, th);
292 }
293 if(dh<sh){
294 DWORD div = sh/th, mod = sh%th;
295 double ratio = (double)th/sh;
296 for(x = 0; x<tw; x++){
297 DWORD alpha = 0;
298 PDWORD line1 = from->m_PixelAdr+from->m_Width*fy+x+fx;
299 PBYTE line2 = (PBYTE)(to->m_PixelAdr+to->m_Width*ty+x+tx);
300 for(y = 0; y<th; y++){
301 DWORD i = div, j = mod;
302 double asum = 0.0, rsum = 0.0, gsum = 0.0, bsum = 0.0;
303 if(alpha){
304 double beta = (double)(th-alpha)/th;
305 SplitColorA(*line1, &a1, &r1, &g1, &b1);
306 line1 += from->m_Width;
307 asum += a1*beta; rsum += r1*beta;
308 gsum += g1*beta; bsum += b1*beta;
309 i--;
310 }
311 do{
312 if(!i){
313 if((alpha += mod)<th) break;
314 alpha -= th;
315 }
316 SplitColorA(*line1, &a1, &r1, &g1, &b1);
317 line1 += from->m_Width;
318 asum += a1; rsum += r1; gsum += g1; bsum += b1;
319 } while(i--);
320 if(alpha){
321 double beta = (double)alpha/th;
322 SplitColorA(*line1, &a1, &r1, &g1, &b1);
323 asum += a1*beta; rsum += r1*beta;
324 gsum += g1*beta; bsum += b1*beta;
325 }
326 *line2++ = (BYTE)(ratio*bsum+0.5);
327 *line2++ = (BYTE)(ratio*gsum+0.5);
328 *line2++ = (BYTE)(ratio*rsum+0.5);
329 *line2 = (BYTE)(ratio*asum+0.5);
330 line2 += (to->m_Width<<2)-3;
331 }
332 }
333 }else{
334 DWORD round = th/2;
335 for(x = 0; x<tw; x++){
336 DWORD alpha = (th+sh)/2;
337 PDWORD begin = from->m_PixelAdr+from->m_Width*fy+x+fx;
338 PDWORD line1 = begin-from->m_Width, end = line1+from->m_Width*sh;
339 PBYTE line2 = (PBYTE)(to->m_PixelAdr+to->m_Width*ty+x+tx);
340 for(y = 0; y<th; y++){
341 SplitColorA(*(line1<begin ? begin : line1), &a1, &r1, &g1, &b1);
342 SplitColorA(*(line1<end ? line1+from->m_Width : end), &a2, &r2, &g2, &b2);
343 DWORD beta = th-alpha;
344 *line2++ = (BYTE)((b1*beta+b2*alpha+round)/th);
345 *line2++ = (BYTE)((g1*beta+g2*alpha+round)/th);
346 *line2++ = (BYTE)((r1*beta+r2*alpha+round)/th);
347 *line2 = (BYTE)((a1*beta+a2*alpha+round)/th);
348 line2 += (to->m_Width<<2)-3;
349 if((alpha += sh)>=th){
350 line1 += from->m_Width;
351 alpha -= th;
352 }
353 }
354 }
355 }
356 }
357 if(!first) return TRUE;
358 first = false;
359 goto HORIZONTAL;
360 }
361
362 /*
363 * 最近点伸縮コピー (範囲チェックなし)
364 *
365 * 戻り値: 成功したら TRUE を返す
366 */
367 BOOL CPixelbit::NearestStamp(
368 CPixelbit *dest, // コピー先画像
369 int dx, int dy, // コピー先座標
370 int dw, int dh, // コピー先サイズ
371 int sx, int sy, // コピー元座標
372 int sw, int sh // コピー元サイズ
373 ){
374 if(dw==sw && dh==sh) return PlainStamp(dest, dx, dy, sx, sy, sw, sh);
375 int wdiv = sw/dw, wmod = sw%dw, wrm = (sw/2)%dw;
376 int hdiv = sh/dh, hmod = sh%dh, alpha = (sh/2)%dh, i;
377 PDWORD line0 = m_PixelAdr+m_Width*(sy+sh/(dh*2))+sx+sw/(dw*2);
378 for(i = 0; i<dh; i++){
379 int beta = wrm;
380 PDWORD line2 = dest->m_PixelAdr+dest->m_Width*(i+dy)+dx;
381 PDWORD line1 = line0, stop = line2+dw;
382 while(line2<stop){
383 *line2++ = *line1;
384 line1 += wdiv+((beta += wmod)>=dw ? ((beta -= dw), 1) : 0);
385 }
386 line0 += m_Width*(hdiv+((alpha += hmod)>=dh ? ((alpha -= dh), 1) : 0));
387 }
388 return TRUE;
389 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26