1 /*
2    Hyllian's 2xBR v3.3b
3 
4    Copyright (C) 2011, 2012 Hyllian/Jararaca - sergiogdb@gmail.com
5 
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU General Public License
8    as published by the Free Software Foundation; either version 2
9    of the License, or (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 
20 */
21 
22 #include <math.h>
23 #include <cstdlib>
24 
25 
26 static unsigned int RGBtoYUV[65536];
27 static unsigned int tbl_5_to_8[32]={0, 8, 16, 25, 33, 41, 49,  58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140, 148, 156, 165, 173, 181, 189,  197, 206, 214, 222, 230, 239, 247, 255};
28 static unsigned int tbl_6_to_8[64]={0, 4, 8, 12, 16, 20, 24,  28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101,  105, 109, 113, 117, 121, 125, 130, 134, 138, 142, 146, 150, 154, 158, 162, 166,  170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 215, 219, 223, 227, 231,  235, 239, 243, 247, 251, 255};
29 
30 #define RED_MASK565   0xF800
31 #define RED_BLUE_MASK565 0xF81F
32 #define GREEN_MASK565 0x07E0
33 #define BLUE_MASK565  0x001F
34 
35 #define RED_MASK555 0x7C00
36 #define GREEN_MASK555 0x03E0
37 #define BLUE_MASK555 0x001F
38 
39 #define PG_LBMASK565 0xF7DE
40 #define PG_LBMASK555 0x7BDE
41 
42 static const unsigned short int pg_red_mask = RED_MASK565;
43 static const unsigned short int pg_red_blue_mask = RED_BLUE_MASK565;
44 static const unsigned short int pg_green_mask = GREEN_MASK565;
45 static const unsigned short int pg_blue_mask = BLUE_MASK565;
46 static const unsigned short int pg_lbmask = PG_LBMASK565;
47 
48 #define ALPHA_BLEND_128_W(dst, src) dst = ((src & pg_lbmask) >> 1) + ((dst & pg_lbmask) >> 1)
49 
50 #define ALPHA_BLEND_32_W(dst, src) \
51 	dst = ( \
52     (pg_red_blue_mask & ((dst & pg_red_blue_mask) + \
53         ((((src & pg_red_blue_mask) - \
54         (dst & pg_red_blue_mask))) >>3))) | \
55     (pg_green_mask & ((dst & pg_green_mask) + \
56         ((((src & pg_green_mask) - \
57         (dst & pg_green_mask))) >>3))))
58 
59 #define ALPHA_BLEND_64_W(dst, src) \
60 	dst = ( \
61     (pg_red_blue_mask & ((dst & pg_red_blue_mask) + \
62         ((((src & pg_red_blue_mask) - \
63         (dst & pg_red_blue_mask))) >>2))) | \
64     (pg_green_mask & ((dst & pg_green_mask) + \
65         ((((src & pg_green_mask) - \
66         (dst & pg_green_mask))) >>2))))
67 
68 #define ALPHA_BLEND_192_W(dst, src) \
69 	dst = ( \
70     (pg_red_blue_mask & ((dst & pg_red_blue_mask) + \
71         ((((src & pg_red_blue_mask) - \
72         (dst & pg_red_blue_mask)) * 3) >>2))) | \
73     (pg_green_mask & ((dst & pg_green_mask) + \
74         ((((src & pg_green_mask) - \
75         (dst & pg_green_mask)) * 3) >>2))))
76 
77 #define ALPHA_BLEND_224_W(dst, src) \
78 	dst = ( \
79     (pg_red_blue_mask & ((dst & pg_red_blue_mask) + \
80         ((((src & pg_red_blue_mask) - \
81         (dst & pg_red_blue_mask)) * 7) >>3))) | \
82     (pg_green_mask & ((dst & pg_green_mask) + \
83         ((((src & pg_green_mask) - \
84         (dst & pg_green_mask)) * 7) >>3))))
85 
86 
87 #define LEFT_UP_2_2X(N3, N2, N1, PIXEL)\
88              ALPHA_BLEND_224_W(E[N3], PIXEL); \
89              ALPHA_BLEND_64_W( E[N2], PIXEL); \
90              E[N1] = E[N2]; \
91 
92 
93 #define LEFT_2_2X(N3, N2, PIXEL)\
94              ALPHA_BLEND_192_W(E[N3], PIXEL); \
95              ALPHA_BLEND_64_W( E[N2], PIXEL); \
96 
97 #define UP_2_2X(N3, N1, PIXEL)\
98              ALPHA_BLEND_192_W(E[N3], PIXEL); \
99              ALPHA_BLEND_64_W( E[N1], PIXEL); \
100 
101 #define DIA_2X(N3, PIXEL)\
102              ALPHA_BLEND_128_W(E[N3], PIXEL); \
103 
104 #define df(A, B)\
105         abs((int)RGBtoYUV[A] - (int)RGBtoYUV[B])\
106 
107 #define eq(A, B)\
108         (df(A, B) < 155)\
109 
initialize()110 static void initialize(){
111     static int initialized;
112     if (initialized){
113         return;
114     }
115     initialized = 1;
116 
117     int format = 0;
118 
119     if (format == 0){ //565
120         for (int c = 0; c < 65536; c++){
121             unsigned int r = tbl_5_to_8[(c &   RED_MASK565) >> 11];
122             unsigned int g = tbl_6_to_8[(c & GREEN_MASK565) >>  5];
123             unsigned int b = tbl_5_to_8[(c &  BLUE_MASK565)      ];
124             unsigned int y = ((r<<4) + (g<<5) + (b<<2));
125             unsigned int u = (   -r  - (g<<1) + (b<<2));
126             unsigned int v = ((r<<1) - (g<<1) - (b>>1));
127             RGBtoYUV[c] = y + u + v;
128         }
129     } else if (format == 1){ //555
130         for (int c = 0; c < 65536; c++) {
131             unsigned int r = tbl_5_to_8[(c &   RED_MASK555) >> 10];
132             unsigned int g = tbl_5_to_8[(c & GREEN_MASK555) >>  5];
133             unsigned int b = tbl_5_to_8[(c &  BLUE_MASK555)      ];
134             unsigned int y = ((r<<4) + (g<<5) + (b<<2));
135             unsigned int u = (   -r  - (g<<1) + (b<<2));
136             unsigned int v = ((r<<1) - (g<<1) - (b>>1));
137             RGBtoYUV[c] = y + u + v;
138         }
139     }
140 }
141 
142 #define xbr2x_do \
143     initialize(); \
144 	\
145     unsigned int e, i, px; \
146     unsigned int ex, ex2, ex3; \
147     unsigned int ke, ki; \
148 	\
149     int nextOutputLine = dstPitch / 2; \
150 	\
151     for (int y = 0; y < Yres; y++){ \
152         unsigned short int * E = (unsigned short *)((char*) pOut + y * dstPitch * 2); \
153 		\
154         unsigned short int * sa2 = (unsigned short *)((char*) pIn + y * srcPitch - 4); \
155         unsigned short int * sa1 = sa2 - srcPitch / 2; \
156         unsigned short int * sa0 = sa1 - srcPitch / 2; \
157         unsigned short int * sa3 = sa2 + srcPitch / 2; \
158         unsigned short int * sa4 = sa3 + srcPitch / 2; \
159 		\
160         if (y <= 1){  \
161             sa0 = sa1; \
162             if (y == 0){ \
163                 sa0 = sa1 = sa2; \
164             } \
165         } \
166 		\
167         if (y >= Yres - 2){ \
168             sa4 = sa3; \
169             if (y == Yres - 1){ \
170                 sa4 = sa3 = sa2; \
171             } \
172         } \
173 		\
174         unsigned char pprev; \
175         unsigned char pprev2; \
176         pprev = pprev2 = 2; \
177 		\
178         for (int x = 0; x < Xres; x++){ \
179             unsigned short B1 = sa0[2]; \
180             unsigned short PB = sa1[2]; \
181             unsigned short PE = sa2[2]; \
182             unsigned short PH = sa3[2]; \
183             unsigned short H5 = sa4[2]; \
184 			\
185             unsigned short A1 = sa0[pprev]; \
186             unsigned short PA = sa1[pprev]; \
187             unsigned short PD = sa2[pprev]; \
188             unsigned short PG = sa3[pprev]; \
189             unsigned short G5 = sa4[pprev]; \
190 			\
191             unsigned short A0 = sa1[pprev2]; \
192             unsigned short D0 = sa2[pprev2]; \
193             unsigned short G0 = sa3[pprev2]; \
194 			\
195             unsigned short C1 = 0; \
196             unsigned short PC = 0; \
197             unsigned short PF = 0; \
198             unsigned short PI = 0; \
199             unsigned short I5 = 0; \
200 			\
201             unsigned short C4 = 0; \
202             unsigned short F4 = 0; \
203             unsigned short I4 = 0; \
204 			\
205             if (x >= Xres - 2){ \
206                 if (x == Xres - 1){ \
207                     C1 = sa0[2]; \
208                     PC = sa1[2]; \
209                     PF = sa2[2]; \
210                     PI = sa3[2]; \
211                     I5 = sa4[2]; \
212 					\
213                     C4 = sa1[2]; \
214                     F4 = sa2[2]; \
215                     I4 = sa3[2]; \
216                 } else { \
217                     C1 = sa0[3]; \
218                     PC = sa1[3]; \
219                     PF = sa2[3]; \
220                     PI = sa3[3]; \
221                     I5 = sa4[3]; \
222 					\
223                     C4 = sa1[3]; \
224                     F4 = sa2[3]; \
225                     I4 = sa3[3]; \
226                 } \
227             } else { \
228                 C1 = sa0[3]; \
229                 PC = sa1[3]; \
230                 PF = sa2[3]; \
231                 PI = sa3[3]; \
232                 I5 = sa4[3]; \
233 				\
234                 C4 = sa1[4]; \
235                 F4 = sa2[4]; \
236                 I4 = sa3[4]; \
237             } \
238 			\
239             E[0] = E[1] = E[nextOutputLine] = E[nextOutputLine + 1] = PE; \
240 			\
241 			FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, 0, 1, nextOutputLine, nextOutputLine+1); \
242 			FILTRO(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0, nextOutputLine, 0, nextOutputLine+1, 1); \
243 			FILTRO(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5, nextOutputLine+1, nextOutputLine, 1, 0); \
244 			FILTRO(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, 1, nextOutputLine+1, 0, nextOutputLine); \
245 			\
246             sa0 += 1; \
247             sa1 += 1; \
248             sa2 += 1; \
249             sa3 += 1; \
250             sa4 += 1; \
251 			\
252             E += 2; \
253 			\
254             if (pprev2){ \
255                 pprev2--; \
256                 pprev = 1; \
257             } \
258         } \
259     } \
260 
xbr2x_a(unsigned char * pIn,unsigned int srcPitch,unsigned char * pOut,unsigned int dstPitch,int Xres,int Yres)261 void xbr2x_a(unsigned char * pIn,  unsigned int srcPitch, unsigned char * pOut, unsigned int dstPitch, int Xres, int Yres)
262 {
263 #define FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3) \
264      ex   = (PE!=PH && PE!=PF); \
265      if ( ex )\
266      {\
267           e = (df(PE,PC)+df(PE,PG)+df(PI,H5)+df(PI,F4))+(df(PH,PF)<<2); \
268           i = (df(PH,PD)+df(PH,I5)+df(PF,I4)+df(PF,PB))+(df(PE,PI)<<2); \
269           if ((e<i)  && ( (!eq(PF,PB) && !eq(PF,PC)) || (!eq(PH,PD) && !eq(PH,PG)) || ((eq(PE,PI) && (!eq(PF,F4) && !eq(PF,I4))) || (!eq(PH,H5) && !eq(PH,I5))) || eq(PE,PG) || eq(PE,PC)) )\
270           {\
271               ke=df(PF,PG); ki=df(PH,PC); \
272               ex2 = (PE!=PC && PB!=PC); ex3 = (PE!=PG && PD!=PG); px = (df(PE,PF) <= df(PE,PH)) ? PF : PH; \
273               if ( ((ke<<1)<=ki) && ex3 && (ke>=(ki<<1)) && ex2 ) \
274               {\
275                      LEFT_UP_2_2X(N3, N2, N1, px)\
276               }\
277               else if ( ((ke<<1)<=ki) && ex3 ) \
278               {\
279                      LEFT_2_2X(N3, N2, px);\
280               }\
281               else if ( (ke>=(ki<<1)) && ex2 ) \
282               {\
283                      UP_2_2X(N3, N1, px);\
284               }\
285               else \
286               {\
287                      DIA_2X(N3, px);\
288               }\
289           }\
290           else if (e<=i)\
291           {\
292                ALPHA_BLEND_128_W( E[N3], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
293           }\
294      }\
295 
296 	xbr2x_do
297 
298 #undef FILTRO
299 }
300 
xbr2x_b(unsigned char * pIn,unsigned int srcPitch,unsigned char * pOut,unsigned int dstPitch,int Xres,int Yres)301 void xbr2x_b(unsigned char * pIn,  unsigned int srcPitch, unsigned char * pOut, unsigned int dstPitch, int Xres, int Yres)
302 {
303 #define FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3) \
304      ex   = (PE!=PH && PE!=PF); \
305      if ( ex )\
306      {\
307           e = (df(PE,PC)+df(PE,PG)+df(PI,H5)+df(PI,F4))+(df(PH,PF)<<2); \
308           i = (df(PH,PD)+df(PH,I5)+df(PF,I4)+df(PF,PB))+(df(PE,PI)<<2); \
309           if ((e<i)  && ( (!eq(PF,PB) && !eq(PH,PD)) || (eq(PE,PI) && (!eq(PF,I4) && !eq(PH,I5))) || eq(PE,PG) || eq(PE,PC)) )\
310           {\
311               ke=df(PF,PG); ki=df(PH,PC); \
312               ex2 = (PE!=PC && PB!=PC); ex3 = (PE!=PG && PD!=PG); px = (df(PE,PF) <= df(PE,PH)) ? PF : PH; \
313               if ( ((ke<<1)<=ki) && ex3 && (ke>=(ki<<1)) && ex2 ) \
314               {\
315                      LEFT_UP_2_2X(N3, N2, N1, px)\
316               }\
317               else if ( ((ke<<1)<=ki) && ex3 ) \
318               {\
319                      LEFT_2_2X(N3, N2, px);\
320               }\
321               else if ( (ke>=(ki<<1)) && ex2 ) \
322               {\
323                      UP_2_2X(N3, N1, px);\
324               }\
325               else \
326               {\
327                      DIA_2X(N3, px);\
328               }\
329           }\
330           else if (e<=i)\
331           {\
332                ALPHA_BLEND_128_W( E[N3], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
333           }\
334      }\
335 
336 	xbr2x_do
337 
338 #undef FILTRO
339 }
340 
xbr2x_c(unsigned char * pIn,unsigned int srcPitch,unsigned char * pOut,unsigned int dstPitch,int Xres,int Yres)341 void xbr2x_c(unsigned char * pIn,  unsigned int srcPitch, unsigned char * pOut, unsigned int dstPitch, int Xres, int Yres)
342 {
343 #define FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3) \
344      ex   = (PE!=PH && PE!=PF); \
345      if ( ex )\
346      {\
347           e = (df(PE,PC)+df(PE,PG)+df(PI,H5)+df(PI,F4))+(df(PH,PF)<<2); \
348           i = (df(PH,PD)+df(PH,I5)+df(PF,I4)+df(PF,PB))+(df(PE,PI)<<2); \
349           if (e<i)\
350           {\
351               ke=df(PF,PG); ki=df(PH,PC); \
352               ex2 = (PE!=PC && PB!=PC); ex3 = (PE!=PG && PD!=PG); px = (df(PE,PF) <= df(PE,PH)) ? PF : PH; \
353               if ( ((ke<<1)<=ki) && ex3 && (ke>=(ki<<1)) && ex2 ) \
354               {\
355                      LEFT_UP_2_2X(N3, N2, N1, px)\
356               }\
357               else if ( ((ke<<1)<=ki) && ex3 ) \
358               {\
359                      LEFT_2_2X(N3, N2, px);\
360               }\
361               else if ( (ke>=(ki<<1)) && ex2 ) \
362               {\
363                      UP_2_2X(N3, N1, px);\
364               }\
365               else \
366               {\
367                      DIA_2X(N3, px);\
368               }\
369           }\
370           else if (e<=i)\
371           {\
372                ALPHA_BLEND_128_W( E[N3], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
373           }\
374      }\
375 
376 	xbr2x_do
377 
378 #undef FILTRO
379 }
380 
381 #undef xbr2x_do
382 
383 #define LEFT_UP_2_3X(N7, N5, N6, N2, N8, PIXEL)\
384              ALPHA_BLEND_192_W(E[N7], PIXEL); \
385              ALPHA_BLEND_64_W( E[N6], PIXEL); \
386              E[N5] = E[N7]; \
387              E[N2] = E[N6]; \
388              E[N8] =  PIXEL;\
389 
390 
391 #define LEFT_2_3X(N7, N5, N6, N8, PIXEL)\
392              ALPHA_BLEND_192_W(E[N7], PIXEL); \
393              ALPHA_BLEND_64_W( E[N5], PIXEL); \
394              ALPHA_BLEND_64_W( E[N6], PIXEL); \
395              E[N8] =  PIXEL;\
396 
397 #define UP_2_3X(N5, N7, N2, N8, PIXEL)\
398              ALPHA_BLEND_192_W(E[N5], PIXEL); \
399              ALPHA_BLEND_64_W( E[N7], PIXEL); \
400              ALPHA_BLEND_64_W( E[N2], PIXEL); \
401              E[N8] =  PIXEL;\
402 
403 #define DIA_3X(N8, N5, N7, PIXEL)\
404              ALPHA_BLEND_224_W(E[N8], PIXEL); \
405              ALPHA_BLEND_32_W(E[N5], PIXEL); \
406              ALPHA_BLEND_32_W(E[N7], PIXEL); \
407 
408 #define xbr3x_do \
409     initialize(); \
410 	\
411     const int nl = dstPitch / 2; \
412     const int nl1 = nl + nl; \
413 	\
414     for (int y = 0; y < Yres; y++){ \
415         unsigned short int * E = (unsigned short *)((char*) pOut + y * dstPitch * 3); \
416 		\
417         unsigned short int * sa2 = (unsigned short *)((char*) pIn + y * srcPitch - 4); \
418         unsigned short int * sa1 = sa2 - srcPitch / 2; \
419         unsigned short int * sa0 = sa1 - srcPitch / 2; \
420         unsigned short int * sa3 = sa2 + srcPitch / 2; \
421         unsigned short int * sa4 = sa3 + srcPitch / 2; \
422 		\
423         if (y <= 1){  \
424             sa0 = sa1; \
425             if (y == 0){ \
426                 sa0 = sa1 = sa2; \
427             } \
428         } \
429 		\
430         if (y >= Yres - 2){ \
431             sa4 = sa3; \
432             if (y == Yres - 1){ \
433                 sa4 = sa3 = sa2; \
434             } \
435         } \
436 		\
437         unsigned char pprev; \
438         unsigned char pprev2; \
439         pprev = pprev2 = 2; \
440 		\
441         for (int x = 0; x < Xres; x++){ \
442             unsigned short B1 = sa0[2]; \
443             unsigned short PB = sa1[2]; \
444             unsigned short PE = sa2[2]; \
445             unsigned short PH = sa3[2]; \
446             unsigned short H5 = sa4[2]; \
447 			\
448             unsigned short A1 = sa0[pprev]; \
449             unsigned short PA = sa1[pprev]; \
450             unsigned short PD = sa2[pprev]; \
451             unsigned short PG = sa3[pprev]; \
452             unsigned short G5 = sa4[pprev]; \
453 			\
454             unsigned short A0 = sa1[pprev2]; \
455             unsigned short D0 = sa2[pprev2]; \
456             unsigned short G0 = sa3[pprev2]; \
457 			\
458             unsigned short C1 = 0; \
459             unsigned short PC = 0; \
460             unsigned short PF = 0; \
461             unsigned short PI = 0; \
462             unsigned short I5 = 0; \
463 			\
464             unsigned short C4 = 0; \
465             unsigned short F4 = 0; \
466             unsigned short I4 = 0; \
467 			\
468             if (x >= Xres - 2){ \
469                 if (x == Xres - 1){ \
470                     C1 = sa0[2]; \
471                     PC = sa1[2]; \
472                     PF = sa2[2]; \
473                     PI = sa3[2]; \
474                     I5 = sa4[2]; \
475 					\
476                     C4 = sa1[2]; \
477                     F4 = sa2[2]; \
478                     I4 = sa3[2]; \
479                 } else { \
480                     C1 = sa0[3]; \
481                     PC = sa1[3]; \
482                     PF = sa2[3]; \
483                     PI = sa3[3]; \
484                     I5 = sa4[3]; \
485 					\
486                     C4 = sa1[3]; \
487                     F4 = sa2[3]; \
488                     I4 = sa3[3]; \
489                 } \
490             } else { \
491                 C1 = sa0[3]; \
492                 PC = sa1[3]; \
493                 PF = sa2[3]; \
494                 PI = sa3[3]; \
495                 I5 = sa4[3]; \
496 				\
497                 C4 = sa1[4]; \
498                 F4 = sa2[4]; \
499                 I4 = sa3[4]; \
500             } \
501 			\
502             unsigned int e, i, px; \
503             unsigned int ex, ex2, ex3; \
504             unsigned int ke, ki; \
505 			\
506             E[0]   = E[1]     = E[2]     = PE; \
507             E[nl]  = E[nl+1]  = E[nl+2]  = PE; \
508             E[nl1] = E[nl1+1] = E[nl1+2] = PE; \
509 			\
510 			FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, 0, 1, 2, nl, nl+1, nl+2, nl1, nl1+1, nl1+2); \
511 			FILTRO(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0, nl1, nl, 0, nl1+1, nl+1, 1, nl1+2, nl+2, 2); \
512 			FILTRO(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5, nl1+2, nl1+1, nl1, nl+2, nl+1, nl, 2, 1, 0); \
513 			FILTRO(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, 2, nl+2, nl1+2, 1, nl+1, nl1+1, 0, nl, nl1); \
514 			\
515             sa0 += 1; \
516             sa1 += 1; \
517             sa2 += 1; \
518             sa3 += 1; \
519             sa4 += 1; \
520 			\
521             E += 3; \
522 			\
523             if (pprev2){ \
524                 pprev2--; \
525                 pprev = 1; \
526             } \
527         } \
528     } \
529 
xbr3x_a(unsigned char * pIn,unsigned int srcPitch,unsigned char * pOut,unsigned int dstPitch,int Xres,int Yres)530 void xbr3x_a(unsigned char * pIn,  unsigned int srcPitch, unsigned char * pOut, unsigned int dstPitch, int Xres, int Yres)
531 {
532 #define FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3, N4, N5, N6, N7, N8) \
533      ex   = (PE!=PH && PE!=PF); \
534      if ( ex )\
535      {\
536           e = (df(PE,PC)+df(PE,PG)+df(PI,H5)+df(PI,F4))+(df(PH,PF)<<2); \
537           i = (df(PH,PD)+df(PH,I5)+df(PF,I4)+df(PF,PB))+(df(PE,PI)<<2); \
538           if ((e<i)  && ( (!eq(PF,PB) && !eq(PF,PC)) || (!eq(PH,PD) && !eq(PH,PG)) || ((eq(PE,PI) && (!eq(PF,F4) && !eq(PF,I4))) || (!eq(PH,H5) && !eq(PH,I5))) || eq(PE,PG) || eq(PE,PC)) )\
539           {\
540               ke=df(PF,PG); ki=df(PH,PC); \
541               ex2 = (PE!=PC && PB!=PC); ex3 = (PE!=PG && PD!=PG); px = (df(PE,PF) <= df(PE,PH)) ? PF : PH; \
542               if ( ((ke<<1)<=ki) && ex3 && (ke>=(ki<<1)) && ex2 ) \
543               {\
544                      LEFT_UP_2_3X(N7, N5, N6, N2, N8, px)\
545               }\
546               else if ( ((ke<<1)<=ki) && ex3 ) \
547               {\
548                      LEFT_2_3X(N7, N5, N6, N8, px);\
549               }\
550               else if ( (ke>=(ki<<1)) && ex2 ) \
551               {\
552                      UP_2_3X(N5, N7, N2, N8, px);\
553               }\
554               else \
555               {\
556                      DIA_3X(N8, N5, N7, px);\
557               }\
558           }\
559           else if (e<=i)\
560           {\
561                ALPHA_BLEND_128_W( E[N8], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
562           }\
563      }\
564 
565 	xbr3x_do
566 
567 #undef FILTRO
568 }
569 
xbr3x_b(unsigned char * pIn,unsigned int srcPitch,unsigned char * pOut,unsigned int dstPitch,int Xres,int Yres)570 void xbr3x_b(unsigned char * pIn,  unsigned int srcPitch, unsigned char * pOut, unsigned int dstPitch, int Xres, int Yres)
571 {
572 #define FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3, N4, N5, N6, N7, N8) \
573      ex   = (PE!=PH && PE!=PF); \
574      if ( ex )\
575      {\
576           e = (df(PE,PC)+df(PE,PG)+df(PI,H5)+df(PI,F4))+(df(PH,PF)<<2); \
577           i = (df(PH,PD)+df(PH,I5)+df(PF,I4)+df(PF,PB))+(df(PE,PI)<<2); \
578           if ((e<i)  && ( (!eq(PF,PB) && !eq(PH,PD)) || (eq(PE,PI) && (!eq(PF,I4) && !eq(PH,I5))) || eq(PE,PG) || eq(PE,PC)) )\
579           {\
580               ke=df(PF,PG); ki=df(PH,PC); \
581               ex2 = (PE!=PC && PB!=PC); ex3 = (PE!=PG && PD!=PG); px = (df(PE,PF) <= df(PE,PH)) ? PF : PH; \
582               if ( ((ke<<1)<=ki) && ex3 && (ke>=(ki<<1)) && ex2 ) \
583               {\
584                      LEFT_UP_2_3X(N7, N5, N6, N2, N8, px)\
585               }\
586               else if ( ((ke<<1)<=ki) && ex3 ) \
587               {\
588                      LEFT_2_3X(N7, N5, N6, N8, px);\
589               }\
590               else if ( (ke>=(ki<<1)) && ex2 ) \
591               {\
592                      UP_2_3X(N5, N7, N2, N8, px);\
593               }\
594               else \
595               {\
596                      DIA_3X(N8, N5, N7, px);\
597               }\
598           }\
599           else if (e<=i)\
600           {\
601                ALPHA_BLEND_128_W( E[N8], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
602           }\
603      }\
604 
605 	xbr3x_do
606 
607 #undef FILTRO
608 }
609 
xbr3x_c(unsigned char * pIn,unsigned int srcPitch,unsigned char * pOut,unsigned int dstPitch,int Xres,int Yres)610 void xbr3x_c(unsigned char * pIn,  unsigned int srcPitch, unsigned char * pOut, unsigned int dstPitch, int Xres, int Yres)
611 {
612 #define FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3, N4, N5, N6, N7, N8) \
613      ex   = (PE!=PH && PE!=PF); \
614      if ( ex )\
615      {\
616           e = (df(PE,PC)+df(PE,PG)+df(PI,H5)+df(PI,F4))+(df(PH,PF)<<2); \
617           i = (df(PH,PD)+df(PH,I5)+df(PF,I4)+df(PF,PB))+(df(PE,PI)<<2); \
618           if (e<i)\
619           {\
620               ke=df(PF,PG); ki=df(PH,PC); \
621               ex2 = (PE!=PC && PB!=PC); ex3 = (PE!=PG && PD!=PG); px = (df(PE,PF) <= df(PE,PH)) ? PF : PH; \
622               if ( ((ke<<1)<=ki) && ex3 && (ke>=(ki<<1)) && ex2 ) \
623               {\
624                      LEFT_UP_2_3X(N7, N5, N6, N2, N8, px)\
625               }\
626               else if ( ((ke<<1)<=ki) && ex3 ) \
627               {\
628                      LEFT_2_3X(N7, N5, N6, N8, px);\
629               }\
630               else if ( (ke>=(ki<<1)) && ex2 ) \
631               {\
632                      UP_2_3X(N5, N7, N2, N8, px);\
633               }\
634               else \
635               {\
636                      DIA_3X(N8, N5, N7, px);\
637               }\
638           }\
639           else if (e<=i)\
640           {\
641                ALPHA_BLEND_128_W( E[N8], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
642           }\
643      }\
644 
645 	xbr3x_do
646 
647 #undef FILTRO
648 }
649 
650 #undef xbr3x_do
651 
652 #define LEFT_UP_2(N15, N14, N11, N13, N12, N10, N7, N3, PIXEL)\
653                                 ALPHA_BLEND_192_W(E[N13], PIXEL); \
654                                 ALPHA_BLEND_64_W( E[N12], PIXEL); \
655                                 E[N15] = E[N14] = E[N11] = PIXEL; \
656                                 E[N10] = E[N3] = E[N12]; \
657                                 E[N7]  = E[N13]; \
658 
659 #define LEFT_2(N15, N14, N11, N13, N12, N10, PIXEL)\
660                                 ALPHA_BLEND_192_W(E[N11], PIXEL); \
661                                 ALPHA_BLEND_192_W(E[N13], PIXEL); \
662                                 ALPHA_BLEND_64_W( E[N10], PIXEL); \
663                                 ALPHA_BLEND_64_W( E[N12], PIXEL); \
664                                 E[N14] = PIXEL; \
665                                 E[N15] = PIXEL; \
666 
667 #define UP_2(N15, N14, N11, N3, N7, N10, PIXEL)\
668                                 ALPHA_BLEND_192_W(E[N14], PIXEL); \
669                                 ALPHA_BLEND_192_W(E[N7 ], PIXEL); \
670                                 ALPHA_BLEND_64_W( E[N10], PIXEL); \
671                                 ALPHA_BLEND_64_W( E[N3 ], PIXEL); \
672                                 E[N11] = PIXEL; \
673                                 E[N15] = PIXEL; \
674 
675 #define DIA(N15, N14, N11, PIXEL)\
676                         ALPHA_BLEND_128_W(E[N11], PIXEL); \
677                         ALPHA_BLEND_128_W(E[N14], PIXEL); \
678                         E[N15] = PIXEL; \
679 
680 #define xbr4x_do \
681     initialize(); \
682 	\
683     const int nl = dstPitch / 2; \
684     const int nl1 = nl + nl; \
685     const int nl2 = nl1 + nl; \
686 	 \
687     for (int y = 0; y < Yres; y++){ \
688         unsigned short int * E = (unsigned short *)((char*) pOut + y * dstPitch * 4); \
689 		\
690         unsigned short int * sa2 = (unsigned short *)((char*) pIn + y * srcPitch - 4); \
691         unsigned short int * sa1 = sa2 - srcPitch / 2; \
692         unsigned short int * sa0 = sa1 - srcPitch / 2; \
693         unsigned short int * sa3 = sa2 + srcPitch / 2; \
694         unsigned short int * sa4 = sa3 + srcPitch / 2; \
695 		 \
696         if (y <= 1){  \
697             sa0 = sa1; \
698             if (y == 0){ \
699                 sa0 = sa1 = sa2; \
700             } \
701         } \
702 		\
703         if (y >= Yres - 2){ \
704             sa4 = sa3; \
705             if (y == Yres - 1){ \
706                 sa4 = sa3 = sa2; \
707             } \
708         } \
709 		\
710         unsigned char pprev; \
711         unsigned char pprev2; \
712         pprev = pprev2 = 2; \
713 		\
714         for (int x = 0; x < Xres; x++){ \
715             unsigned short B1 = sa0[2]; \
716             unsigned short PB = sa1[2]; \
717             unsigned short PE = sa2[2]; \
718             unsigned short PH = sa3[2]; \
719             unsigned short H5 = sa4[2]; \
720 			\
721             unsigned short A1 = sa0[pprev]; \
722             unsigned short PA = sa1[pprev]; \
723             unsigned short PD = sa2[pprev]; \
724             unsigned short PG = sa3[pprev]; \
725             unsigned short G5 = sa4[pprev]; \
726 			\
727             unsigned short A0 = sa1[pprev2]; \
728             unsigned short D0 = sa2[pprev2]; \
729             unsigned short G0 = sa3[pprev2]; \
730 			 \
731             unsigned short C1 = 0; \
732             unsigned short PC = 0; \
733             unsigned short PF = 0; \
734             unsigned short PI = 0; \
735             unsigned short I5 = 0; \
736 			\
737             unsigned short C4 = 0; \
738             unsigned short F4 = 0; \
739             unsigned short I4 = 0; \
740 			\
741             if (x >= Xres - 2){ \
742                 if (x == Xres - 1){ \
743                     C1 = sa0[2]; \
744                     PC = sa1[2]; \
745                     PF = sa2[2]; \
746                     PI = sa3[2]; \
747                     I5 = sa4[2]; \
748 					\
749                     C4 = sa1[2]; \
750                     F4 = sa2[2]; \
751                     I4 = sa3[2]; \
752                 } else { \
753                     C1 = sa0[3]; \
754                     PC = sa1[3]; \
755                     PF = sa2[3]; \
756                     PI = sa3[3]; \
757                     I5 = sa4[3]; \
758 					\
759                     C4 = sa1[3]; \
760                     F4 = sa2[3]; \
761                     I4 = sa3[3]; \
762                 } \
763             } else { \
764                 C1 = sa0[3]; \
765                 PC = sa1[3]; \
766                 PF = sa2[3]; \
767                 PI = sa3[3]; \
768                 I5 = sa4[3]; \
769 				\
770                 C4 = sa1[4]; \
771                 F4 = sa2[4]; \
772                 I4 = sa3[4]; \
773             } \
774 			\
775             unsigned int e, i, px; \
776             unsigned int ex, ex2, ex3; \
777             unsigned int ke, ki; \
778 			\
779             E[0]   = E[1]     = E[2]     = E[3]     = PE; \
780             E[nl]  = E[nl+1]  = E[nl+2]  = E[nl+3]  = PE; \
781             E[nl1] = E[nl1+1] = E[nl1+2] = E[nl1+3] = PE; \
782             E[nl2] = E[nl2+1] = E[nl2+2] = E[nl2+3] = PE; \
783 			\
784 			FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, nl2+3, nl2+2, nl1+3,  3,  nl+3, nl1+2, nl2+1, nl2,  nl1+1,  nl+2, 2,  1, nl+1, nl1, nl, 0); \
785 			FILTRO(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0,  3,  nl+3,  2,  0,  1,  nl+2, nl1+3, nl2+3, nl1+2,  nl+1, nl,  nl1, nl1+1,nl2+2,nl2+1,nl2); \
786 			FILTRO(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5,  0,  1,  nl, nl2,  nl1,  nl+1,  2,  3,  nl+2,  nl1+1, nl2+1,nl2+2,nl1+2, nl+3,nl1+3,nl2+3); \
787 			FILTRO(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, nl2,  nl1, nl2+1, nl2+3, nl2+2,  nl1+1,  nl,  0,  nl+1, nl1+2, nl1+3, nl+3, nl+2, 1, 2, 3); \
788 			\
789             sa0 += 1; \
790             sa1 += 1; \
791             sa2 += 1; \
792             sa3 += 1; \
793             sa4 += 1; \
794 			\
795             E += 4; \
796 			\
797             if (pprev2){ \
798                 pprev2--; \
799                 pprev = 1; \
800             } \
801         } \
802     } \
803 
804 
xbr4x_a(unsigned char * pIn,unsigned int srcPitch,unsigned char * pOut,unsigned int dstPitch,int Xres,int Yres)805 void xbr4x_a(unsigned char * pIn,  unsigned int srcPitch, unsigned char * pOut, unsigned int dstPitch, int Xres, int Yres)
806 {
807 #define FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N15, N14, N11, N3, N7, N10, N13, N12, N9, N6, N2, N1, N5, N8, N4, N0) \
808      ex   = (PE!=PH && PE!=PF); \
809      if ( ex )\
810      {\
811           e = (df(PE,PC)+df(PE,PG)+df(PI,H5)+df(PI,F4))+(df(PH,PF)<<2); \
812           i = (df(PH,PD)+df(PH,I5)+df(PF,I4)+df(PF,PB))+(df(PE,PI)<<2); \
813           if ((e<i)  && ( (!eq(PF,PB) && !eq(PF,PC)) || (!eq(PH,PD) && !eq(PH,PG)) || ((eq(PE,PI) && (!eq(PF,F4) && !eq(PF,I4))) || (!eq(PH,H5) && !eq(PH,I5))) || eq(PE,PG) || eq(PE,PC)) )\
814           {\
815               ke=df(PF,PG); ki=df(PH,PC); \
816               ex2 = (PE!=PC && PB!=PC); ex3 = (PE!=PG && PD!=PG); px = (df(PE,PF) <= df(PE,PH)) ? PF : PH; \
817               if ( ((ke<<1)<=ki) && ex3 && (ke>=(ki<<1)) && ex2 ) \
818               {\
819                      LEFT_UP_2(N15, N14, N11, N13, N12, N10, N7, N3, px)\
820               }\
821               else if ( ((ke<<1)<=ki) && ex3 ) \
822               {\
823                      LEFT_2(N15, N14, N11, N13, N12, N10, px)\
824               }\
825               else if ( (ke>=(ki<<1)) && ex2 ) \
826               {\
827                      UP_2(N15, N14, N11, N3, N7, N10, px)\
828               }\
829               else \
830               {\
831                      DIA(N15, N14, N11, px)\
832               }\
833           }\
834           else if (e<=i)\
835           {\
836                ALPHA_BLEND_128_W( E[N15], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
837           }\
838      }\
839 
840 	xbr4x_do
841 
842 #undef FILTRO
843 }
844 
xbr4x_b(unsigned char * pIn,unsigned int srcPitch,unsigned char * pOut,unsigned int dstPitch,int Xres,int Yres)845 void xbr4x_b(unsigned char * pIn,  unsigned int srcPitch, unsigned char * pOut, unsigned int dstPitch, int Xres, int Yres)
846 {
847 #define FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N15, N14, N11, N3, N7, N10, N13, N12, N9, N6, N2, N1, N5, N8, N4, N0) \
848      ex   = (PE!=PH && PE!=PF); \
849      if ( ex )\
850      {\
851           e = (df(PE,PC)+df(PE,PG)+df(PI,H5)+df(PI,F4))+(df(PH,PF)<<2); \
852           i = (df(PH,PD)+df(PH,I5)+df(PF,I4)+df(PF,PB))+(df(PE,PI)<<2); \
853           if ((e<i)  && ( (!eq(PF,PB) && !eq(PH,PD)) || (eq(PE,PI) && (!eq(PF,I4) && !eq(PH,I5))) || eq(PE,PG) || eq(PE,PC)) )\
854           {\
855               ke=df(PF,PG); ki=df(PH,PC); \
856               ex2 = (PE!=PC && PB!=PC); ex3 = (PE!=PG && PD!=PG); px = (df(PE,PF) <= df(PE,PH)) ? PF : PH; \
857               if ( ((ke<<1)<=ki) && ex3 && (ke>=(ki<<1)) && ex2 ) \
858               {\
859                      LEFT_UP_2(N15, N14, N11, N13, N12, N10, N7, N3, px)\
860               }\
861               else if ( ((ke<<1)<=ki) && ex3 ) \
862               {\
863                      LEFT_2(N15, N14, N11, N13, N12, N10, px)\
864               }\
865               else if ( (ke>=(ki<<1)) && ex2 ) \
866               {\
867                      UP_2(N15, N14, N11, N3, N7, N10, px)\
868               }\
869               else \
870               {\
871                      DIA(N15, N14, N11, px)\
872               }\
873           }\
874           else if (e<=i)\
875           {\
876                ALPHA_BLEND_128_W( E[N15], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
877           }\
878      }\
879 
880 	xbr4x_do
881 
882 #undef FILTRO
883 }
884 
xbr4x_c(unsigned char * pIn,unsigned int srcPitch,unsigned char * pOut,unsigned int dstPitch,int Xres,int Yres)885 void xbr4x_c(unsigned char * pIn,  unsigned int srcPitch, unsigned char * pOut, unsigned int dstPitch, int Xres, int Yres)
886 {
887 #define FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N15, N14, N11, N3, N7, N10, N13, N12, N9, N6, N2, N1, N5, N8, N4, N0) \
888      ex   = (PE!=PH && PE!=PF); \
889      if ( ex )\
890      {\
891           e = (df(PE,PC)+df(PE,PG)+df(PI,H5)+df(PI,F4))+(df(PH,PF)<<2); \
892           i = (df(PH,PD)+df(PH,I5)+df(PF,I4)+df(PF,PB))+(df(PE,PI)<<2); \
893           if (e<i)\
894           {\
895               ke=df(PF,PG); ki=df(PH,PC); \
896               ex2 = (PE!=PC && PB!=PC); ex3 = (PE!=PG && PD!=PG); px = (df(PE,PF) <= df(PE,PH)) ? PF : PH; \
897               if ( ((ke<<1)<=ki) && ex3 && (ke>=(ki<<1)) && ex2 ) \
898               {\
899                      LEFT_UP_2(N15, N14, N11, N13, N12, N10, N7, N3, px)\
900               }\
901               else if ( ((ke<<1)<=ki) && ex3 ) \
902               {\
903                      LEFT_2(N15, N14, N11, N13, N12, N10, px)\
904               }\
905               else if ( (ke>=(ki<<1)) && ex2 ) \
906               {\
907                      UP_2(N15, N14, N11, N3, N7, N10, px)\
908               }\
909               else \
910               {\
911                      DIA(N15, N14, N11, px)\
912               }\
913           }\
914           else if (e<=i)\
915           {\
916                ALPHA_BLEND_128_W( E[N15], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
917           }\
918      }\
919 
920 	xbr4x_do
921 
922 #undef FILTRO
923 }
924 
925 #undef xbr4x_do
926