9 #include "img_format.h"
13 //===========================================================================//
15 /* FIXME: these all belong in the context, not as globals! */
17 static uint32_t colorMask
= 0xF7DEF7DE;
18 static uint32_t lowPixelMask
= 0x08210821;
19 static uint32_t qcolorMask
= 0xE79CE79C;
20 static uint32_t qlowpixelMask
= 0x18631863;
21 static uint32_t redblueMask
= 0xF81F;
22 static uint32_t greenMask
= 0x7E0;
23 static int PixelsPerMask
= 2;
25 #define makecol(r,g,b) (r+(g<<8)+(b<<16))
26 #define makecol_depth(d,r,g,b) (r+(g<<8)+(b<<16))
28 static int Init_2xSaI(int d
)
31 int minr
= 0, ming
= 0, minb
= 0;
34 // if (d != 15 && d != 16 && d != 24 && d != 32)
37 /* Get lowest color bit */
38 for (i
= 0; i
< 255; i
++) {
40 minr
= makecol(i
, 0, 0);
42 ming
= makecol(0, i
, 0);
44 minb
= makecol(0, 0, i
);
47 colorMask
= (makecol_depth(d
, 255, 0, 0) - minr
) | (makecol_depth(d
, 0, 255, 0) - ming
) | (makecol_depth(d
, 0, 0, 255) - minb
);
48 lowPixelMask
= minr
| ming
| minb
;
49 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
);
50 qlowpixelMask
= (minr
* 3) | (ming
* 3) | (minb
* 3);
51 redblueMask
= makecol_depth(d
, 255, 0, 255);
52 greenMask
= makecol_depth(d
, 0, 255, 0);
54 PixelsPerMask
= (d
<= 16) ? 2 : 1;
56 if (PixelsPerMask
== 2) {
57 colorMask
|= (colorMask
<< 16);
58 qcolorMask
|= (qcolorMask
<< 16);
59 lowPixelMask
|= (lowPixelMask
<< 16);
60 qlowpixelMask
|= (qlowpixelMask
<< 16);
63 // TRACE("Color Mask: 0x%lX\n", colorMask);
64 // TRACE("Low Pixel Mask: 0x%lX\n", lowPixelMask);
65 // TRACE("QColor Mask: 0x%lX\n", qcolorMask);
66 // TRACE("QLow Pixel Mask: 0x%lX\n", qlowpixelMask);
72 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
74 #define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask))
76 #define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) \
77 + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask)
80 static void Super2xSaI_ex(uint8_t *src
, uint32_t src_pitch
,
81 uint8_t *dst
, uint32_t dst_pitch
,
82 uint32_t width
, uint32_t height
, int sbpp
) {
86 unsigned char *src_line
[4];
88 /* Point to the first 3 lines. */
91 src_line
[2] = src
+ src_pitch
;
92 src_line
[3] = src
+ src_pitch
* 2;
96 if (PixelsPerMask
== 2) {
98 sbp
= (unsigned short*)src_line
[0];
99 color
[0] = *sbp
; color
[1] = color
[0]; color
[2] = color
[0]; color
[3] = color
[0];
100 color
[4] = color
[0]; color
[5] = color
[0]; color
[6] = *(sbp
+ 1); color
[7] = *(sbp
+ 2);
101 sbp
= (unsigned short*)src_line
[2];
102 color
[8] = *sbp
; color
[9] = color
[8]; color
[10] = *(sbp
+ 1); color
[11] = *(sbp
+ 2);
103 sbp
= (unsigned short*)src_line
[3];
104 color
[12] = *sbp
; color
[13] = color
[12]; color
[14] = *(sbp
+ 1); color
[15] = *(sbp
+ 2);
108 lbp
= (uint32_t*)src_line
[0];
109 color
[0] = *lbp
; color
[1] = color
[0]; color
[2] = color
[0]; color
[3] = color
[0];
110 color
[4] = color
[0]; color
[5] = color
[0]; color
[6] = *(lbp
+ 1); color
[7] = *(lbp
+ 2);
111 lbp
= (uint32_t*)src_line
[2];
112 color
[8] = *lbp
; color
[9] = color
[8]; color
[10] = *(lbp
+ 1); color
[11] = *(lbp
+ 2);
113 lbp
= (uint32_t*)src_line
[3];
114 color
[12] = *lbp
; color
[13] = color
[12]; color
[14] = *(lbp
+ 1); color
[15] = *(lbp
+ 2);
117 for (y
= 0; y
< height
; y
++) {
118 unsigned char *dst_line
[2];
120 dst_line
[0] = dst
+ dst_pitch
*2*y
;
121 dst_line
[1] = dst
+ dst_pitch
*(2*y
+1);
123 /* Todo: x = width - 2, x = width - 1 */
125 for (x
= 0; x
< width
; x
++) {
126 uint32_t product1a
, product1b
, product2a
, product2b
;
128 //--------------------------------------- B0 B1 B2 B3 0 1 2 3
129 // 4 5* 6 S2 -> 4 5* 6 7
130 // 1 2 3 S1 8 9 10 11
131 // A0 A1 A2 A3 12 13 14 15
132 //--------------------------------------
133 if (color
[9] == color
[6] && color
[5] != color
[10]) {
134 product2b
= color
[9];
135 product1b
= product2b
;
137 else if (color
[5] == color
[10] && color
[9] != color
[6]) {
138 product2b
= color
[5];
139 product1b
= product2b
;
141 else if (color
[5] == color
[10] && color
[9] == color
[6]) {
144 r
+= GET_RESULT(color
[6], color
[5], color
[8], color
[13]);
145 r
+= GET_RESULT(color
[6], color
[5], color
[4], color
[1]);
146 r
+= GET_RESULT(color
[6], color
[5], color
[14], color
[11]);
147 r
+= GET_RESULT(color
[6], color
[5], color
[2], color
[7]);
150 product1b
= color
[6];
152 product1b
= color
[5];
154 product1b
= INTERPOLATE(color
[5], color
[6]);
156 product2b
= product1b
;
160 if (color
[6] == color
[10] && color
[10] == color
[13] && color
[9] != color
[14] && color
[10] != color
[12])
161 product2b
= Q_INTERPOLATE(color
[10], color
[10], color
[10], color
[9]);
162 else if (color
[5] == color
[9] && color
[9] == color
[14] && color
[13] != color
[10] && color
[9] != color
[15])
163 product2b
= Q_INTERPOLATE(color
[9], color
[9], color
[9], color
[10]);
165 product2b
= INTERPOLATE(color
[9], color
[10]);
167 if (color
[6] == color
[10] && color
[6] == color
[1] && color
[5] != color
[2] && color
[6] != color
[0])
168 product1b
= Q_INTERPOLATE(color
[6], color
[6], color
[6], color
[5]);
169 else if (color
[5] == color
[9] && color
[5] == color
[2] && color
[1] != color
[6] && color
[5] != color
[3])
170 product1b
= Q_INTERPOLATE(color
[6], color
[5], color
[5], color
[5]);
172 product1b
= INTERPOLATE(color
[5], color
[6]);
175 if (color
[5] == color
[10] && color
[9] != color
[6] && color
[4] == color
[5] && color
[5] != color
[14])
176 product2a
= INTERPOLATE(color
[9], color
[5]);
177 else if (color
[5] == color
[8] && color
[6] == color
[5] && color
[4] != color
[9] && color
[5] != color
[12])
178 product2a
= INTERPOLATE(color
[9], color
[5]);
180 product2a
= color
[9];
182 if (color
[9] == color
[6] && color
[5] != color
[10] && color
[8] == color
[9] && color
[9] != color
[2])
183 product1a
= INTERPOLATE(color
[9], color
[5]);
184 else if (color
[4] == color
[9] && color
[10] == color
[9] && color
[8] != color
[5] && color
[9] != color
[0])
185 product1a
= INTERPOLATE(color
[9], color
[5]);
187 product1a
= color
[5];
189 if (PixelsPerMask
== 2) {
190 *((uint32_t *) (&dst_line
[0][x
* 4])) = product1a
| (product1b
<< 16);
191 *((uint32_t *) (&dst_line
[1][x
* 4])) = product2a
| (product2b
<< 16);
194 *((uint32_t *) (&dst_line
[0][x
* 8])) = product1a
;
195 *((uint32_t *) (&dst_line
[0][x
* 8 + 4])) = product1b
;
196 *((uint32_t *) (&dst_line
[1][x
* 8])) = product2a
;
197 *((uint32_t *) (&dst_line
[1][x
* 8 + 4])) = product2b
;
200 /* Move color matrix forward */
201 color
[0] = color
[1]; color
[4] = color
[5]; color
[8] = color
[9]; color
[12] = color
[13];
202 color
[1] = color
[2]; color
[5] = color
[6]; color
[9] = color
[10]; color
[13] = color
[14];
203 color
[2] = color
[3]; color
[6] = color
[7]; color
[10] = color
[11]; color
[14] = color
[15];
207 if (PixelsPerMask
== 2) {
208 color
[3] = *(((unsigned short*)src_line
[0]) + x
);
209 color
[7] = *(((unsigned short*)src_line
[1]) + x
);
210 color
[11] = *(((unsigned short*)src_line
[2]) + x
);
211 color
[15] = *(((unsigned short*)src_line
[3]) + x
);
214 color
[3] = *(((uint32_t*)src_line
[0]) + x
);
215 color
[7] = *(((uint32_t*)src_line
[1]) + x
);
216 color
[11] = *(((uint32_t*)src_line
[2]) + x
);
217 color
[15] = *(((uint32_t*)src_line
[3]) + x
);
223 /* We're done with one line, so we shift the source lines up */
224 src_line
[0] = src_line
[1];
225 src_line
[1] = src_line
[2];
226 src_line
[2] = src_line
[3];
230 src_line
[3] = src_line
[2];
232 src_line
[3] = src_line
[2] + src_pitch
;
234 /* Then shift the color matrix up */
235 if (PixelsPerMask
== 2) {
237 sbp
= (unsigned short*)src_line
[0];
238 color
[0] = *sbp
; color
[1] = color
[0]; color
[2] = *(sbp
+ 1); color
[3] = *(sbp
+ 2);
239 sbp
= (unsigned short*)src_line
[1];
240 color
[4] = *sbp
; color
[5] = color
[4]; color
[6] = *(sbp
+ 1); color
[7] = *(sbp
+ 2);
241 sbp
= (unsigned short*)src_line
[2];
242 color
[8] = *sbp
; color
[9] = color
[9]; color
[10] = *(sbp
+ 1); color
[11] = *(sbp
+ 2);
243 sbp
= (unsigned short*)src_line
[3];
244 color
[12] = *sbp
; color
[13] = color
[12]; color
[14] = *(sbp
+ 1); color
[15] = *(sbp
+ 2);
248 lbp
= (uint32_t*)src_line
[0];
249 color
[0] = *lbp
; color
[1] = color
[0]; color
[2] = *(lbp
+ 1); color
[3] = *(lbp
+ 2);
250 lbp
= (uint32_t*)src_line
[1];
251 color
[4] = *lbp
; color
[5] = color
[4]; color
[6] = *(lbp
+ 1); color
[7] = *(lbp
+ 2);
252 lbp
= (uint32_t*)src_line
[2];
253 color
[8] = *lbp
; color
[9] = color
[9]; color
[10] = *(lbp
+ 1); color
[11] = *(lbp
+ 2);
254 lbp
= (uint32_t*)src_line
[3];
255 color
[12] = *lbp
; color
[13] = color
[12]; color
[14] = *(lbp
+ 1); color
[15] = *(lbp
+ 2);
263 //===========================================================================//
265 static int config(struct vf_instance
* vf
,
266 int width
, int height
, int d_width
, int d_height
,
267 unsigned int flags
, unsigned int outfmt
){
269 Init_2xSaI(outfmt
&255);
271 return vf_next_config(vf
,2*width
,2*height
,2*d_width
,2*d_height
,flags
,outfmt
);
274 static int put_image(struct vf_instance
* vf
, mp_image_t
*mpi
, double pts
){
277 // hope we'll get DR buffer:
278 dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
279 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
282 Super2xSaI_ex(mpi
->planes
[0], mpi
->stride
[0],
283 dmpi
->planes
[0], dmpi
->stride
[0],
284 mpi
->w
, mpi
->h
, mpi
->bpp
/8);
286 return vf_next_put_image(vf
,dmpi
, pts
);
289 //===========================================================================//
291 static int query_format(struct vf_instance
* vf
, unsigned int fmt
){
293 // case IMGFMT_BGR15:
294 // case IMGFMT_BGR16:
296 return vf_next_query_format(vf
,fmt
);
301 static int open(vf_instance_t
*vf
, char* args
){
303 vf
->put_image
=put_image
;
304 vf
->query_format
=query_format
;
308 const vf_info_t vf_info_2xsai
= {
309 "2xSai BGR bitmap 2x scaler",
312 "http://elektron.its.tudelft.nl/~dalikifa/",
317 //===========================================================================//