2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "img_format.h"
31 //===========================================================================//
33 /* FIXME: these all belong in the context, not as globals! */
35 static uint32_t colorMask
= 0xF7DEF7DE;
36 static uint32_t lowPixelMask
= 0x08210821;
37 static uint32_t qcolorMask
= 0xE79CE79C;
38 static uint32_t qlowpixelMask
= 0x18631863;
39 static uint32_t redblueMask
= 0xF81F;
40 static uint32_t greenMask
= 0x7E0;
41 static int PixelsPerMask
= 2;
43 #define makecol(r,g,b) (r+(g<<8)+(b<<16))
44 #define makecol_depth(d,r,g,b) (r+(g<<8)+(b<<16))
46 static int Init_2xSaI(int d
)
49 int minr
= 0, ming
= 0, minb
= 0;
52 // if (d != 15 && d != 16 && d != 24 && d != 32)
55 /* Get lowest color bit */
56 for (i
= 0; i
< 255; i
++) {
58 minr
= makecol(i
, 0, 0);
60 ming
= makecol(0, i
, 0);
62 minb
= makecol(0, 0, i
);
65 colorMask
= (makecol_depth(d
, 255, 0, 0) - minr
) | (makecol_depth(d
, 0, 255, 0) - ming
) | (makecol_depth(d
, 0, 0, 255) - minb
);
66 lowPixelMask
= minr
| ming
| minb
;
67 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
);
68 qlowpixelMask
= (minr
* 3) | (ming
* 3) | (minb
* 3);
69 redblueMask
= makecol_depth(d
, 255, 0, 255);
70 greenMask
= makecol_depth(d
, 0, 255, 0);
72 PixelsPerMask
= (d
<= 16) ? 2 : 1;
74 if (PixelsPerMask
== 2) {
75 colorMask
|= (colorMask
<< 16);
76 qcolorMask
|= (qcolorMask
<< 16);
77 lowPixelMask
|= (lowPixelMask
<< 16);
78 qlowpixelMask
|= (qlowpixelMask
<< 16);
81 // TRACE("Color Mask: 0x%lX\n", colorMask);
82 // TRACE("Low Pixel Mask: 0x%lX\n", lowPixelMask);
83 // TRACE("QColor Mask: 0x%lX\n", qcolorMask);
84 // TRACE("QLow Pixel Mask: 0x%lX\n", qlowpixelMask);
90 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
92 #define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask))
94 #define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) \
95 + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask)
98 static void Super2xSaI_ex(uint8_t *src
, uint32_t src_pitch
,
99 uint8_t *dst
, uint32_t dst_pitch
,
100 uint32_t width
, uint32_t height
, int sbpp
)
105 unsigned char *src_line
[4];
107 /* Point to the first 3 lines. */
110 src_line
[2] = src
+ src_pitch
;
111 src_line
[3] = src
+ src_pitch
* 2;
115 if (PixelsPerMask
== 2) {
117 sbp
= (unsigned short*)src_line
[0];
118 color
[0] = *sbp
; color
[1] = color
[0]; color
[2] = color
[0]; color
[3] = color
[0];
119 color
[4] = color
[0]; color
[5] = color
[0]; color
[6] = *(sbp
+ 1); color
[7] = *(sbp
+ 2);
120 sbp
= (unsigned short*)src_line
[2];
121 color
[8] = *sbp
; color
[9] = color
[8]; color
[10] = *(sbp
+ 1); color
[11] = *(sbp
+ 2);
122 sbp
= (unsigned short*)src_line
[3];
123 color
[12] = *sbp
; color
[13] = color
[12]; color
[14] = *(sbp
+ 1); color
[15] = *(sbp
+ 2);
127 lbp
= (uint32_t*)src_line
[0];
128 color
[0] = *lbp
; color
[1] = color
[0]; color
[2] = color
[0]; color
[3] = color
[0];
129 color
[4] = color
[0]; color
[5] = color
[0]; color
[6] = *(lbp
+ 1); color
[7] = *(lbp
+ 2);
130 lbp
= (uint32_t*)src_line
[2];
131 color
[8] = *lbp
; color
[9] = color
[8]; color
[10] = *(lbp
+ 1); color
[11] = *(lbp
+ 2);
132 lbp
= (uint32_t*)src_line
[3];
133 color
[12] = *lbp
; color
[13] = color
[12]; color
[14] = *(lbp
+ 1); color
[15] = *(lbp
+ 2);
136 for (y
= 0; y
< height
; y
++) {
137 unsigned char *dst_line
[2];
139 dst_line
[0] = dst
+ dst_pitch
*2*y
;
140 dst_line
[1] = dst
+ dst_pitch
*(2*y
+1);
142 /* Todo: x = width - 2, x = width - 1 */
144 for (x
= 0; x
< width
; x
++) {
145 uint32_t product1a
, product1b
, product2a
, product2b
;
147 //--------------------------------------- B0 B1 B2 B3 0 1 2 3
148 // 4 5* 6 S2 -> 4 5* 6 7
149 // 1 2 3 S1 8 9 10 11
150 // A0 A1 A2 A3 12 13 14 15
151 //--------------------------------------
152 if (color
[9] == color
[6] && color
[5] != color
[10]) {
153 product2b
= color
[9];
154 product1b
= product2b
;
156 else if (color
[5] == color
[10] && color
[9] != color
[6]) {
157 product2b
= color
[5];
158 product1b
= product2b
;
160 else if (color
[5] == color
[10] && color
[9] == color
[6]) {
163 r
+= GET_RESULT(color
[6], color
[5], color
[8], color
[13]);
164 r
+= GET_RESULT(color
[6], color
[5], color
[4], color
[1]);
165 r
+= GET_RESULT(color
[6], color
[5], color
[14], color
[11]);
166 r
+= GET_RESULT(color
[6], color
[5], color
[2], color
[7]);
169 product1b
= color
[6];
171 product1b
= color
[5];
173 product1b
= INTERPOLATE(color
[5], color
[6]);
175 product2b
= product1b
;
179 if (color
[6] == color
[10] && color
[10] == color
[13] && color
[9] != color
[14] && color
[10] != color
[12])
180 product2b
= Q_INTERPOLATE(color
[10], color
[10], color
[10], color
[9]);
181 else if (color
[5] == color
[9] && color
[9] == color
[14] && color
[13] != color
[10] && color
[9] != color
[15])
182 product2b
= Q_INTERPOLATE(color
[9], color
[9], color
[9], color
[10]);
184 product2b
= INTERPOLATE(color
[9], color
[10]);
186 if (color
[6] == color
[10] && color
[6] == color
[1] && color
[5] != color
[2] && color
[6] != color
[0])
187 product1b
= Q_INTERPOLATE(color
[6], color
[6], color
[6], color
[5]);
188 else if (color
[5] == color
[9] && color
[5] == color
[2] && color
[1] != color
[6] && color
[5] != color
[3])
189 product1b
= Q_INTERPOLATE(color
[6], color
[5], color
[5], color
[5]);
191 product1b
= INTERPOLATE(color
[5], color
[6]);
194 if (color
[5] == color
[10] && color
[9] != color
[6] && color
[4] == color
[5] && color
[5] != color
[14])
195 product2a
= INTERPOLATE(color
[9], color
[5]);
196 else if (color
[5] == color
[8] && color
[6] == color
[5] && color
[4] != color
[9] && color
[5] != color
[12])
197 product2a
= INTERPOLATE(color
[9], color
[5]);
199 product2a
= color
[9];
201 if (color
[9] == color
[6] && color
[5] != color
[10] && color
[8] == color
[9] && color
[9] != color
[2])
202 product1a
= INTERPOLATE(color
[9], color
[5]);
203 else if (color
[4] == color
[9] && color
[10] == color
[9] && color
[8] != color
[5] && color
[9] != color
[0])
204 product1a
= INTERPOLATE(color
[9], color
[5]);
206 product1a
= color
[5];
208 if (PixelsPerMask
== 2) {
209 *((uint32_t *) (&dst_line
[0][x
* 4])) = product1a
| (product1b
<< 16);
210 *((uint32_t *) (&dst_line
[1][x
* 4])) = product2a
| (product2b
<< 16);
213 *((uint32_t *) (&dst_line
[0][x
* 8])) = product1a
;
214 *((uint32_t *) (&dst_line
[0][x
* 8 + 4])) = product1b
;
215 *((uint32_t *) (&dst_line
[1][x
* 8])) = product2a
;
216 *((uint32_t *) (&dst_line
[1][x
* 8 + 4])) = product2b
;
219 /* Move color matrix forward */
220 color
[0] = color
[1]; color
[4] = color
[5]; color
[8] = color
[9]; color
[12] = color
[13];
221 color
[1] = color
[2]; color
[5] = color
[6]; color
[9] = color
[10]; color
[13] = color
[14];
222 color
[2] = color
[3]; color
[6] = color
[7]; color
[10] = color
[11]; color
[14] = color
[15];
226 if (PixelsPerMask
== 2) {
227 color
[3] = *(((unsigned short*)src_line
[0]) + x
);
228 color
[7] = *(((unsigned short*)src_line
[1]) + x
);
229 color
[11] = *(((unsigned short*)src_line
[2]) + x
);
230 color
[15] = *(((unsigned short*)src_line
[3]) + x
);
233 color
[3] = *(((uint32_t*)src_line
[0]) + x
);
234 color
[7] = *(((uint32_t*)src_line
[1]) + x
);
235 color
[11] = *(((uint32_t*)src_line
[2]) + x
);
236 color
[15] = *(((uint32_t*)src_line
[3]) + x
);
242 /* We're done with one line, so we shift the source lines up */
243 src_line
[0] = src_line
[1];
244 src_line
[1] = src_line
[2];
245 src_line
[2] = src_line
[3];
249 src_line
[3] = src_line
[2];
251 src_line
[3] = src_line
[2] + src_pitch
;
253 /* Then shift the color matrix up */
254 if (PixelsPerMask
== 2) {
256 sbp
= (unsigned short*)src_line
[0];
257 color
[0] = *sbp
; color
[1] = color
[0]; color
[2] = *(sbp
+ 1); color
[3] = *(sbp
+ 2);
258 sbp
= (unsigned short*)src_line
[1];
259 color
[4] = *sbp
; color
[5] = color
[4]; color
[6] = *(sbp
+ 1); color
[7] = *(sbp
+ 2);
260 sbp
= (unsigned short*)src_line
[2];
261 color
[8] = *sbp
; color
[9] = color
[9]; color
[10] = *(sbp
+ 1); color
[11] = *(sbp
+ 2);
262 sbp
= (unsigned short*)src_line
[3];
263 color
[12] = *sbp
; color
[13] = color
[12]; color
[14] = *(sbp
+ 1); color
[15] = *(sbp
+ 2);
267 lbp
= (uint32_t*)src_line
[0];
268 color
[0] = *lbp
; color
[1] = color
[0]; color
[2] = *(lbp
+ 1); color
[3] = *(lbp
+ 2);
269 lbp
= (uint32_t*)src_line
[1];
270 color
[4] = *lbp
; color
[5] = color
[4]; color
[6] = *(lbp
+ 1); color
[7] = *(lbp
+ 2);
271 lbp
= (uint32_t*)src_line
[2];
272 color
[8] = *lbp
; color
[9] = color
[9]; color
[10] = *(lbp
+ 1); color
[11] = *(lbp
+ 2);
273 lbp
= (uint32_t*)src_line
[3];
274 color
[12] = *lbp
; color
[13] = color
[12]; color
[14] = *(lbp
+ 1); color
[15] = *(lbp
+ 2);
282 //===========================================================================//
284 static int config(struct vf_instance
*vf
,
285 int width
, int height
, int d_width
, int d_height
,
286 unsigned int flags
, unsigned int outfmt
){
288 Init_2xSaI(outfmt
&255);
290 return vf_next_config(vf
,2*width
,2*height
,2*d_width
,2*d_height
,flags
,outfmt
);
293 static int put_image(struct vf_instance
*vf
, mp_image_t
*mpi
, double pts
){
296 // hope we'll get DR buffer:
297 dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
298 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
301 Super2xSaI_ex(mpi
->planes
[0], mpi
->stride
[0],
302 dmpi
->planes
[0], dmpi
->stride
[0],
303 mpi
->w
, mpi
->h
, mpi
->bpp
/8);
305 return vf_next_put_image(vf
,dmpi
, pts
);
308 //===========================================================================//
310 static int query_format(struct vf_instance
*vf
, unsigned int fmt
){
312 // case IMGFMT_BGR15:
313 // case IMGFMT_BGR16:
315 return vf_next_query_format(vf
,fmt
);
320 static int vf_open(vf_instance_t
*vf
, char *args
){
322 vf
->put_image
=put_image
;
323 vf
->query_format
=query_format
;
327 const vf_info_t vf_info_2xsai
= {
328 "2xSai BGR bitmap 2x scaler",
331 "http://elektron.its.tudelft.nl/~dalikifa/",
336 //===========================================================================//