1 /*
2 * 2xSaI engine. This file was obtained from:
3 * http://bob.allegronetwork.com/projects.html
4 * Authors: Derek Liauw Kie Fa/Kreed, Robert J Ohannessian, Peter Wang
5 */
6
7 /*
8 2xSaI
9 ~~~~~
10
11 Copyright (c) Derek Liauw Kie Fa, 1999
12 Modifications for Allegro 3.9+ comptibility by Robert J Ohannessian.
13
14 Comments, Suggestions, Questions, Bugs etc.:
15 derek-liauw@usa.net
16 void_star_@excite.com
17
18 Original web site: http://members.xoom.com/derek_liauw/
19
20 This program is free for non-commercial use.
21
22
23 Disclaimer
24 ----------
25 #include <std_disclaimer.h>
26 Use this program at your own risk. This program was not intended to do
27 anything malicious, but we are not responsible for any damage or loss
28 that may arise by the use of this program.
29 */
30
31 #include <string.h>
32 #include <allegro.h>
33 #include <allegro/internal/aintern.h>
34 #include "2xsai.h"
35
36
37
38 static __UInt32 colorMask = 0xF7DEF7DE;
39 static __UInt32 lowPixelMask = 0x08210821;
40 static __UInt32 qcolorMask = 0xE79CE79C;
41 static __UInt32 qlowpixelMask = 0x18631863;
42 static __UInt32 redblueMask = 0xF81F;
43 static __UInt32 greenMask = 0x7E0;
44 static int PixelsPerMask = 2;
45 static int xsai_depth = 0;
46
47
48
Init_2xSaI(int d)49 int Init_2xSaI(int d)
50 {
51
52 int minr = 0, ming = 0, minb = 0;
53 int i;
54
55 if (d != 15 && d != 16 && d != 24 && d != 32)
56 return -1;
57
58 /* Get lowest color bit */
59 for (i = 0; i < 255; i++) {
60 if (!minr)
61 minr = makecol(i, 0, 0);
62 if (!ming)
63 ming = makecol(0, i, 0);
64 if (!minb)
65 minb = makecol(0, 0, i);
66 }
67
68 colorMask = (makecol_depth(d, 255, 0, 0) - minr) | (makecol_depth(d, 0, 255, 0) - ming) | (makecol_depth(d, 0, 0, 255) - minb);
69 lowPixelMask = minr | ming | minb;
70 qcolorMask = (makecol_depth(d, 255, 0, 0) - 3 * minr) | (makecol_depth(d, 0, 255, 0) - 3 * ming) | (makecol_depth(d, 0, 0, 255) - 3 * minb);
71 qlowpixelMask = (minr * 3) | (ming * 3) | (minb * 3);
72 redblueMask = makecol_depth(d, 255, 0, 255);
73 greenMask = makecol_depth(d, 0, 255, 0);
74
75 PixelsPerMask = (d <= 16) ? 2 : 1;
76
77 if (PixelsPerMask == 2) {
78 colorMask |= (colorMask << 16);
79 qcolorMask |= (qcolorMask << 16);
80 lowPixelMask |= (lowPixelMask << 16);
81 qlowpixelMask |= (qlowpixelMask << 16);
82 }
83
84 /*TRACE("Color Mask: 0x%lX\n", colorMask);
85 TRACE("Low Pixel Mask: 0x%lX\n", lowPixelMask);
86 TRACE("QColor Mask: 0x%lX\n", qcolorMask);
87 TRACE("QLow Pixel Mask: 0x%lX\n", qlowpixelMask);*/
88
89 xsai_depth = d;
90
91 return 0;
92 }
93
94
95 /*static int GetResult1(__UInt32 A, __UInt32 B, __UInt32 C, __UInt32 D)
96 {
97 int x = 0;
98 int y = 0;
99 int r = 0;
100 if (A == C)
101 x += 1;
102 else if (B == C)
103 y += 1;
104 if (A == D)
105 x += 1;
106 else if (B == D)
107 y += 1;
108 if (x <= 1)
109 r += 1;
110 if (y <= 1)
111 r -= 1;
112 return r;
113 }
114
115 static int GetResult2(__UInt32 A, __UInt32 B, __UInt32 C, __UInt32 D, __UInt32 E)
116 {
117 int x = 0;
118 int y = 0;
119 int r = 0;
120 if (A == C)
121 x += 1;
122 else if (B == C)
123 y += 1;
124 if (A == D)
125 x += 1;
126 else if (B == D)
127 y += 1;
128 if (x <= 1)
129 r -= 1;
130 if (y <= 1)
131 r += 1;
132 return r;
133 }*/
134
135
136 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
137
138 #define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask))
139
140 #define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) \
141 + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask)
142
143
144 /* Clipping Macro, stolen from Allegro, modified to work with 2xSaI */
145 #define BLIT_CLIP2(src, dest, s_x, s_y, d_x, d_y, w, h, xscale, yscale) \
146 /* check for ridiculous cases */ \
147 if ((s_x >= src->cr) || (s_y >= src->cb) || \
148 (d_x >= dest->cr) || (d_y >= dest->cb)) \
149 return; \
150 \
151 if ((s_x + w < src->cl) || (s_y + h < src->ct) || \
152 (d_x + w * xscale < dest->cl) || (d_y + h * yscale < dest->ct)) \
153 return; \
154 \
155 if (xscale < 1 || yscale < 1) \
156 return; \
157 \
158 /* clip src left */ \
159 if (s_x < src->cl) { \
160 w += s_x; \
161 d_x -= s_x * xscale; \
162 s_x = src->cl; \
163 } \
164 \
165 /* clip src top */ \
166 if (s_y < src->ct) { \
167 h += s_y; \
168 d_y -= s_y * yscale; \
169 s_y = src->ct; \
170 } \
171 \
172 /* clip src right */ \
173 if (s_x + w > src->cr) \
174 w = src->cr - s_x; \
175 \
176 /* clip src bottom */ \
177 if (s_y + h > src->cb) \
178 h = src->cb - s_y; \
179 \
180 /* clip dest left */ \
181 if (d_x < dest->cl) { \
182 d_x -= dest->cl; \
183 w += d_x / xscale; \
184 s_x -= d_x / xscale; \
185 d_x = dest->cl; \
186 } \
187 \
188 /* clip dest top */ \
189 if (d_y < dest->ct) { \
190 d_y -= dest->ct; \
191 h += d_y / yscale; \
192 s_y -= d_y / yscale; \
193 d_y = dest->ct; \
194 } \
195 \
196 /* clip dest right */ \
197 if (d_x + w * xscale > dest->cr) \
198 w = (dest->cr - d_x) / xscale; \
199 \
200 /* clip dest bottom */ \
201 if (d_y + h * yscale > dest->cb) \
202 h = (dest->cb - d_y) / yscale; \
203 \
204 /* bottle out if zero size */ \
205 if ((w <= 0) || (h <= 0)) \
206 return;
207
208
209 static unsigned char *src_line[4];
210 static unsigned char *dst_line[2];
211
212
Super2xSaI(BITMAP * src,BITMAP * dest,int s_x,int s_y,int d_x,int d_y,int w,int h)213 void Super2xSaI(BITMAP * src, BITMAP * dest, int s_x, int s_y, int d_x, int d_y, int w, int h)
214 {
215 int sbpp, dbpp;
216
217 BITMAP *dst2 = NULL;
218
219 if (!src || !dest)
220 return;
221
222 sbpp = bitmap_color_depth(src);
223 dbpp = bitmap_color_depth(dest);
224
225 if ((sbpp != xsai_depth) || (sbpp != dbpp)) /* Must be same color depth */
226 return;
227
228 BLIT_CLIP2(src, dest, s_x, s_y, d_x, d_y, w, h, 2, 2);
229
230 if (w < 4 || h < 4) { /* Image is too small to be 2xSaI'ed. */
231 stretch_blit(src, dest, s_x, s_y, w, h, d_x, d_y, w * 2, h * 2);
232 return;
233 }
234
235 sbpp = BYTES_PER_PIXEL(sbpp);
236 if (d_x || d_y)
237 dst2 = create_sub_bitmap(dest, d_x, d_y, w * 2, h * 2);
238
239 Super2xSaI_ex(src->line[s_y] + s_x * sbpp, (unsigned int)(src->line[1] - src->line[0]), NULL, dst2 ? dst2 : dest, w, h);
240
241 if (dst2)
242 destroy_bitmap(dst2);
243
244 return;
245 }
246
Super2xSaI_ex(__UInt8 * src,__UInt32 src_pitch,__UInt8 * unused,BITMAP * dest,__UInt32 width,__UInt32 height)247 void Super2xSaI_ex(__UInt8 *src, __UInt32 src_pitch, __UInt8 *unused, BITMAP *dest, __UInt32 width, __UInt32 height) {
248
249 int j, v;
250 unsigned int x, y;
251 int sbpp = BYTES_PER_PIXEL(bitmap_color_depth(dest));
252 unsigned long color[16];
253
254 /* Point to the first 3 lines. */
255 src_line[0] = src;
256 src_line[1] = src;
257 src_line[2] = src + src_pitch;
258 src_line[3] = src + src_pitch * 2;
259
260 /* Can we write the results directly? */
261 if (is_video_bitmap(dest) || is_planar_bitmap(dest)) {
262 dst_line[0] = malloc(sizeof(char) * sbpp * width);
263 dst_line[1] = malloc(sizeof(char) * sbpp * width);
264 v = 1;
265 }
266 else {
267 dst_line[0] = dest->line[0];
268 dst_line[1] = dest->line[1];
269 v = 0;
270 }
271
272 /* Set destination */
273 bmp_select(dest);
274
275 x = 0, y = 0;
276
277 if (PixelsPerMask == 2) {
278 unsigned short *sbp;
279 sbp = (unsigned short*)src_line[0];
280 color[0] = *sbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0];
281 color[4] = color[0]; color[5] = color[0]; color[6] = *(sbp + 1); color[7] = *(sbp + 2);
282 sbp = (unsigned short*)src_line[2];
283 color[8] = *sbp; color[9] = color[8]; color[10] = *(sbp + 1); color[11] = *(sbp + 2);
284 sbp = (unsigned short*)src_line[3];
285 color[12] = *sbp; color[13] = color[12]; color[14] = *(sbp + 1); color[15] = *(sbp + 2);
286 }
287 else {
288 unsigned long *lbp;
289 lbp = (unsigned long*)src_line[0];
290 color[0] = *lbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0];
291 color[4] = color[0]; color[5] = color[0]; color[6] = *(lbp + 1); color[7] = *(lbp + 2);
292 lbp = (unsigned long*)src_line[2];
293 color[8] = *lbp; color[9] = color[8]; color[10] = *(lbp + 1); color[11] = *(lbp + 2);
294 lbp = (unsigned long*)src_line[3];
295 color[12] = *lbp; color[13] = color[12]; color[14] = *(lbp + 1); color[15] = *(lbp + 2);
296 }
297
298 for (y = 0; y < height; y++) {
299
300 /* Todo: x = width - 2, x = width - 1 */
301
302 for (x = 0; x < width; x++) {
303 unsigned long product1a, product1b, product2a, product2b;
304
305 /*
306 --------------------------------------- B0 B1 B2 B3 0 1 2 3
307 4 5* 6 S2 -> 4 5* 6 7
308 1 2 3 S1 8 9 10 11
309 A0 A1 A2 A3 12 13 14 15
310 --------------------------------------
311 */
312 if (color[9] == color[6] && color[5] != color[10]) {
313 product2b = color[9];
314 product1b = product2b;
315 }
316 else if (color[5] == color[10] && color[9] != color[6]) {
317 product2b = color[5];
318 product1b = product2b;
319 }
320 else if (color[5] == color[10] && color[9] == color[6]) {
321 int r = 0;
322
323 r += GET_RESULT(color[6], color[5], color[8], color[13]);
324 r += GET_RESULT(color[6], color[5], color[4], color[1]);
325 r += GET_RESULT(color[6], color[5], color[14], color[11]);
326 r += GET_RESULT(color[6], color[5], color[2], color[7]);
327
328 if (r > 0)
329 product1b = color[6];
330 else if (r < 0)
331 product1b = color[5];
332 else
333 product1b = INTERPOLATE(color[5], color[6]);
334
335 product2b = product1b;
336
337 }
338 else {
339 if (color[6] == color[10] && color[10] == color[13] && color[9] != color[14] && color[10] != color[12])
340 product2b = Q_INTERPOLATE(color[10], color[10], color[10], color[9]);
341 else if (color[5] == color[9] && color[9] == color[14] && color[13] != color[10] && color[9] != color[15])
342 product2b = Q_INTERPOLATE(color[9], color[9], color[9], color[10]);
343 else
344 product2b = INTERPOLATE(color[9], color[10]);
345
346 if (color[6] == color[10] && color[6] == color[1] && color[5] != color[2] && color[6] != color[0])
347 product1b = Q_INTERPOLATE(color[6], color[6], color[6], color[5]);
348 else if (color[5] == color[9] && color[5] == color[2] && color[1] != color[6] && color[5] != color[3])
349 product1b = Q_INTERPOLATE(color[6], color[5], color[5], color[5]);
350 else
351 product1b = INTERPOLATE(color[5], color[6]);
352 }
353
354 if (color[5] == color[10] && color[9] != color[6] && color[4] == color[5] && color[5] != color[14])
355 product2a = INTERPOLATE(color[9], color[5]);
356 else if (color[5] == color[8] && color[6] == color[5] && color[4] != color[9] && color[5] != color[12])
357 product2a = INTERPOLATE(color[9], color[5]);
358 else
359 product2a = color[9];
360
361 if (color[9] == color[6] && color[5] != color[10] && color[8] == color[9] && color[9] != color[2])
362 product1a = INTERPOLATE(color[9], color[5]);
363 else if (color[4] == color[9] && color[10] == color[9] && color[8] != color[5] && color[9] != color[0])
364 product1a = INTERPOLATE(color[9], color[5]);
365 else
366 product1a = color[5];
367
368 if (PixelsPerMask == 2) {
369 *((unsigned long *) (&dst_line[0][x * 4])) = product1a | (product1b << 16);
370 *((unsigned long *) (&dst_line[1][x * 4])) = product2a | (product2b << 16);
371 }
372 else {
373 *((unsigned long *) (&dst_line[0][x * 8])) = product1a;
374 *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b;
375 *((unsigned long *) (&dst_line[1][x * 8])) = product2a;
376 *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b;
377 }
378
379 /* Move color matrix forward */
380 color[0] = color[1]; color[4] = color[5]; color[8] = color[9]; color[12] = color[13];
381 color[1] = color[2]; color[5] = color[6]; color[9] = color[10]; color[13] = color[14];
382 color[2] = color[3]; color[6] = color[7]; color[10] = color[11]; color[14] = color[15];
383
384 if (x < width - 3) {
385 x += 3;
386 if (PixelsPerMask == 2) {
387 color[3] = *(((unsigned short*)src_line[0]) + x);
388 color[7] = *(((unsigned short*)src_line[1]) + x);
389 color[11] = *(((unsigned short*)src_line[2]) + x);
390 color[15] = *(((unsigned short*)src_line[3]) + x);
391 }
392 else {
393 color[3] = *(((unsigned long*)src_line[0]) + x);
394 color[7] = *(((unsigned long*)src_line[1]) + x);
395 color[11] = *(((unsigned long*)src_line[2]) + x);
396 color[15] = *(((unsigned long*)src_line[3]) + x);
397 }
398 x -= 3;
399 }
400 }
401
402 /* We're done with one line, so we shift the source lines up */
403 src_line[0] = src_line[1];
404 src_line[1] = src_line[2];
405 src_line[2] = src_line[3];
406
407 /* Read next line */
408 if (y + 3 >= height)
409 src_line[3] = src_line[2];
410 else
411 src_line[3] = src_line[2] + src_pitch;
412
413 /* Then shift the color matrix up */
414 if (PixelsPerMask == 2) {
415 unsigned short *sbp;
416 sbp = (unsigned short*)src_line[0];
417 color[0] = *sbp; color[1] = color[0]; color[2] = *(sbp + 1); color[3] = *(sbp + 2);
418 sbp = (unsigned short*)src_line[1];
419 color[4] = *sbp; color[5] = color[4]; color[6] = *(sbp + 1); color[7] = *(sbp + 2);
420 sbp = (unsigned short*)src_line[2];
421 color[8] = *sbp; color[9] = color[9]; color[10] = *(sbp + 1); color[11] = *(sbp + 2);
422 sbp = (unsigned short*)src_line[3];
423 color[12] = *sbp; color[13] = color[12]; color[14] = *(sbp + 1); color[15] = *(sbp + 2);
424 }
425 else {
426 unsigned long *lbp;
427 lbp = (unsigned long*)src_line[0];
428 color[0] = *lbp; color[1] = color[0]; color[2] = *(lbp + 1); color[3] = *(lbp + 2);
429 lbp = (unsigned long*)src_line[1];
430 color[4] = *lbp; color[5] = color[4]; color[6] = *(lbp + 1); color[7] = *(lbp + 2);
431 lbp = (unsigned long*)src_line[2];
432 color[8] = *lbp; color[9] = color[9]; color[10] = *(lbp + 1); color[11] = *(lbp + 2);
433 lbp = (unsigned long*)src_line[3];
434 color[12] = *lbp; color[13] = color[12]; color[14] = *(lbp + 1); color[15] = *(lbp + 2);
435 }
436
437
438 /* Write the 2 lines, if not already done so */
439 if (v) {
440 unsigned long dst_addr;
441
442 dst_addr = bmp_write_line(dest, y * 2);
443 for (j = 0; j < dest->w * sbpp; j += sizeof(long))
444 bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[0] + j)));
445
446 dst_addr = bmp_write_line(dest, y * 2 + 1);
447 for (j = 0; j < dest->w * sbpp; j += sizeof(long))
448 bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[1] + j)));
449 }
450 else {
451 if (y < height - 1) {
452 dst_line[0] = dest->line[y * 2 + 2];
453 dst_line[1] = dest->line[y * 2 + 3];
454 }
455 }
456 }
457 bmp_unwrite_line(dest);
458
459 if (v) {
460 free(dst_line[0]);
461 free(dst_line[1]);
462 }
463 }
464
465
466
SuperEagle(BITMAP * src,BITMAP * dest,int s_x,int s_y,int d_x,int d_y,int w,int h)467 void SuperEagle(BITMAP * src, BITMAP * dest, int s_x, int s_y, int d_x, int d_y, int w, int h)
468 {
469 int sbpp, dbpp;
470
471 BITMAP *dst2 = NULL;
472
473 if (!src || !dest)
474 return;
475
476 sbpp = bitmap_color_depth(src);
477 dbpp = bitmap_color_depth(dest);
478
479 if ((sbpp != xsai_depth) || (sbpp != dbpp)) /* Must be same color depth */
480 return;
481
482 BLIT_CLIP2(src, dest, s_x, s_y, d_x, d_y, w, h, 2, 2);
483
484 if (w < 4 || h < 4) { /* Image is too small to be 2xSaI'ed. */
485 stretch_blit(src, dest, s_x, s_y, w, h, d_x, d_y, w * 2, h * 2);
486 return;
487 }
488
489 sbpp = BYTES_PER_PIXEL(sbpp);
490 if (d_x || d_y)
491 dst2 = create_sub_bitmap(dest, d_x, d_y, w * 2, h * 2);
492
493 SuperEagle_ex(src->line[s_y] + s_x * sbpp, (unsigned int)(src->line[1] - src->line[0]), NULL, dst2 ? dst2 : dest, w, h);
494
495 if (dst2)
496 destroy_bitmap(dst2);
497
498 return;
499 }
500
SuperEagle_ex(__UInt8 * src,__UInt32 src_pitch,__UInt8 * unused,BITMAP * dest,__UInt32 width,__UInt32 height)501 void SuperEagle_ex(__UInt8 *src, __UInt32 src_pitch, __UInt8 *unused, BITMAP *dest, __UInt32 width, __UInt32 height) {
502
503 int j, v;
504 unsigned int x, y;
505 int sbpp = BYTES_PER_PIXEL(bitmap_color_depth(dest));
506 unsigned long color[12];
507
508 /* Point to the first 3 lines. */
509 src_line[0] = src;
510 src_line[1] = src;
511 src_line[2] = src + src_pitch;
512 src_line[3] = src + src_pitch * 2;
513
514 /* Can we write the results directly? */
515 if (is_video_bitmap(dest) || is_planar_bitmap(dest)) {
516 dst_line[0] = malloc(sizeof(char) * sbpp * width);
517 dst_line[1] = malloc(sizeof(char) * sbpp * width);
518 v = 1;
519 }
520 else {
521 dst_line[0] = dest->line[0];
522 dst_line[1] = dest->line[1];
523 v = 0;
524 }
525
526 /* Set destination */
527 bmp_select(dest);
528
529 x = 0, y = 0;
530
531 if (PixelsPerMask == 2) {
532 unsigned short *sbp;
533 sbp = (unsigned short*)src_line[0];
534 color[0] = *sbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0];
535 color[4] = *(sbp + 1); color[5] = *(sbp + 2);
536 sbp = (unsigned short*)src_line[2];
537 color[6] = *sbp; color[7] = color[6]; color[8] = *(sbp + 1); color[9] = *(sbp + 2);
538 sbp = (unsigned short*)src_line[3];
539 color[10] = *sbp; color[11] = *(sbp + 1);
540 }
541 else {
542 unsigned long *lbp;
543 lbp = (unsigned long*)src_line[0];
544 color[0] = *lbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0];
545 color[4] = *(lbp + 1); color[5] = *(lbp + 2);
546 lbp = (unsigned long*)src_line[2];
547 color[6] = *lbp; color[7] = color[6]; color[8] = *(lbp + 1); color[9] = *(lbp + 2);
548 lbp = (unsigned long*)src_line[3];
549 color[10] = *lbp; color[11] = *(lbp + 1);
550 }
551
552 for (y = 0; y < height; y++) {
553
554 /* Todo: x = width - 2, x = width - 1 */
555
556 for (x = 0; x < width; x++) {
557 unsigned long product1a, product1b, product2a, product2b;
558
559 /*
560 --------------------------------------- B1 B2 0 1
561 4 5 6 S2 -> 2 3 4 5
562 1 2 3 S1 6 7 8 9
563 A1 A2 10 11
564 */
565
566 if (color[7] == color[4] && color[3] != color[8]) {
567 product1b = product2a = color[7];
568
569 if ((color[6] == color[7]) || (color[4] == color[1]))
570 product1a = INTERPOLATE(color[7], INTERPOLATE(color[7], color[3]));
571 else
572 product1a = INTERPOLATE(color[3], color[4]);
573
574 if ((color[4] == color[5]) || (color[7] == color[10]))
575 product2b = INTERPOLATE(color[7], INTERPOLATE(color[7], color[8]));
576 else
577 product2b = INTERPOLATE(color[7], color[8]);
578 }
579 else if (color[3] == color[8] && color[7] != color[4]) {
580 product2b = product1a = color[3];
581
582 if ((color[0] == color[3]) || (color[5] == color[9]))
583 product1b = INTERPOLATE(color[3], INTERPOLATE(color[3], color[4]));
584 else
585 product1b = INTERPOLATE(color[3], color[1]);
586
587 if ((color[8] == color[11]) || (color[2] == color[3]))
588 product2a = INTERPOLATE(color[3], INTERPOLATE(color[3], color[2]));
589 else
590 product2a = INTERPOLATE(color[7], color[8]);
591
592 }
593 else if (color[3] == color[8] && color[7] == color[4]) {
594 register int r = 0;
595
596 r += GET_RESULT(color[4], color[3], color[6], color[10]);
597 r += GET_RESULT(color[4], color[3], color[2], color[0]);
598 r += GET_RESULT(color[4], color[3], color[11], color[9]);
599 r += GET_RESULT(color[4], color[3], color[1], color[5]);
600
601 if (r > 0) {
602 product1b = product2a = color[7];
603 product1a = product2b = INTERPOLATE(color[3], color[4]);
604 }
605 else if (r < 0) {
606 product2b = product1a = color[3];
607 product1b = product2a = INTERPOLATE(color[3], color[4]);
608 }
609 else {
610 product2b = product1a = color[3];
611 product1b = product2a = color[7];
612 }
613 }
614 else {
615 product2b = product1a = INTERPOLATE(color[7], color[4]);
616 product2b = Q_INTERPOLATE(color[8], color[8], color[8], product2b);
617 product1a = Q_INTERPOLATE(color[3], color[3], color[3], product1a);
618
619 product2a = product1b = INTERPOLATE(color[3], color[8]);
620 product2a = Q_INTERPOLATE(color[7], color[7], color[7], product2a);
621 product1b = Q_INTERPOLATE(color[4], color[4], color[4], product1b);
622 }
623
624 if (PixelsPerMask == 2) {
625 *((unsigned long *) (&dst_line[0][x * 4])) = product1a | (product1b << 16);
626 *((unsigned long *) (&dst_line[1][x * 4])) = product2a | (product2b << 16);
627 }
628 else {
629 *((unsigned long *) (&dst_line[0][x * 8])) = product1a;
630 *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b;
631 *((unsigned long *) (&dst_line[1][x * 8])) = product2a;
632 *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b;
633 }
634
635 /* Move color matrix forward */
636 color[0] = color[1];
637 color[2] = color[3]; color[3] = color[4]; color[4] = color[5];
638 color[6] = color[7]; color[7] = color[8]; color[8] = color[9];
639 color[10] = color[11];
640
641 if (x < width - 2) {
642 x += 2;
643 if (PixelsPerMask == 2) {
644 color[1] = *(((unsigned short*)src_line[0]) + x);
645 if (x < width) {
646 color[5] = *(((unsigned short*)src_line[1]) + x + 1);
647 color[9] = *(((unsigned short*)src_line[2]) + x + 1);
648 }
649 color[11] = *(((unsigned short*)src_line[3]) + x);
650 }
651 else {
652 color[1] = *(((unsigned long*)src_line[0]) + x);
653 if (x < width) {
654 color[5] = *(((unsigned long*)src_line[1]) + x + 1);
655 color[9] = *(((unsigned long*)src_line[2]) + x + 1);
656 }
657 color[11] = *(((unsigned long*)src_line[3]) + x);
658 }
659 x -= 2;
660 }
661 }
662
663 /* We're done with one line, so we shift the source lines up */
664 src_line[0] = src_line[1];
665 src_line[1] = src_line[2];
666 src_line[2] = src_line[3];
667
668 /* Read next line */
669 if (y + 3 >= height)
670 src_line[3] = src_line[2];
671 else
672 src_line[3] = src_line[2] + src_pitch;
673
674 /* Then shift the color matrix up */
675 if (PixelsPerMask == 2) {
676 unsigned short *sbp;
677 sbp = (unsigned short*)src_line[0];
678 color[0] = *sbp; color[1] = *(sbp + 1);
679 sbp = (unsigned short*)src_line[1];
680 color[2] = *sbp; color[3] = color[2]; color[4] = *(sbp + 1); color[5] = *(sbp + 2);
681 sbp = (unsigned short*)src_line[2];
682 color[6] = *sbp; color[7] = color[6]; color[8] = *(sbp + 1); color[9] = *(sbp + 2);
683 sbp = (unsigned short*)src_line[3];
684 color[10] = *sbp; color[11] = *(sbp + 1);
685 }
686 else {
687 unsigned long *lbp;
688 lbp = (unsigned long*)src_line[0];
689 color[0] = *lbp; color[1] = *(lbp + 1);
690 lbp = (unsigned long*)src_line[1];
691 color[2] = *lbp; color[3] = color[2]; color[4] = *(lbp + 1); color[5] = *(lbp + 2);
692 lbp = (unsigned long*)src_line[2];
693 color[6] = *lbp; color[7] = color[6]; color[8] = *(lbp + 1); color[9] = *(lbp + 2);
694 lbp = (unsigned long*)src_line[3];
695 color[10] = *lbp; color[11] = *(lbp + 1);
696 }
697
698
699 /* Write the 2 lines, if not already done so */
700 if (v) {
701 unsigned long dst_addr;
702
703 dst_addr = bmp_write_line(dest, y * 2);
704 for (j = 0; j < dest->w * sbpp; j += sizeof(long))
705 bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[0] + j)));
706
707 dst_addr = bmp_write_line(dest, y * 2 + 1);
708 for (j = 0; j < dest->w * sbpp; j += sizeof(long))
709 bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[1] + j)));
710 }
711 else {
712 if (y < height - 1) {
713 dst_line[0] = dest->line[y * 2 + 2];
714 dst_line[1] = dest->line[y * 2 + 3];
715 }
716 }
717 }
718 bmp_unwrite_line(dest);
719
720 if (v) {
721 free(dst_line[0]);
722 free(dst_line[1]);
723 }
724 }
725