Use proper length specifiers in mp_msg calls, fixes the warnings:
[mplayer/greg.git] / libmpcodecs / vf_2xsai.c
blob358d8049f2f370c1da308bbde402ad0b2fd0a013
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <inttypes.h>
6 #include "config.h"
7 #include "mp_msg.h"
9 #include "img_format.h"
10 #include "mp_image.h"
11 #include "vf.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;
24 static int xsai_depth = 0;
26 #define makecol(r,g,b) (r+(g<<8)+(b<<16))
27 #define makecol_depth(d,r,g,b) (r+(g<<8)+(b<<16))
29 int Init_2xSaI(int d)
32 int minr = 0, ming = 0, minb = 0;
33 int i;
35 // if (d != 15 && d != 16 && d != 24 && d != 32)
36 // return -1;
38 /* Get lowest color bit */
39 for (i = 0; i < 255; i++) {
40 if (!minr)
41 minr = makecol(i, 0, 0);
42 if (!ming)
43 ming = makecol(0, i, 0);
44 if (!minb)
45 minb = makecol(0, 0, i);
48 colorMask = (makecol_depth(d, 255, 0, 0) - minr) | (makecol_depth(d, 0, 255, 0) - ming) | (makecol_depth(d, 0, 0, 255) - minb);
49 lowPixelMask = minr | ming | minb;
50 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);
51 qlowpixelMask = (minr * 3) | (ming * 3) | (minb * 3);
52 redblueMask = makecol_depth(d, 255, 0, 255);
53 greenMask = makecol_depth(d, 0, 255, 0);
55 PixelsPerMask = (d <= 16) ? 2 : 1;
57 if (PixelsPerMask == 2) {
58 colorMask |= (colorMask << 16);
59 qcolorMask |= (qcolorMask << 16);
60 lowPixelMask |= (lowPixelMask << 16);
61 qlowpixelMask |= (qlowpixelMask << 16);
64 // TRACE("Color Mask: 0x%lX\n", colorMask);
65 // TRACE("Low Pixel Mask: 0x%lX\n", lowPixelMask);
66 // TRACE("QColor Mask: 0x%lX\n", qcolorMask);
67 // TRACE("QLow Pixel Mask: 0x%lX\n", qlowpixelMask);
69 xsai_depth = d;
71 return 0;
75 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
77 #define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask))
79 #define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) \
80 + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask)
83 static unsigned char *src_line[4];
84 static unsigned char *dst_line[2];
86 void Super2xSaI_ex(uint8_t *src, uint32_t src_pitch,
87 uint8_t *dst, uint32_t dst_pitch,
88 uint32_t width, uint32_t height, int sbpp) {
90 unsigned int x, y;
91 uint32_t color[16];
93 /* Point to the first 3 lines. */
94 src_line[0] = src;
95 src_line[1] = src;
96 src_line[2] = src + src_pitch;
97 src_line[3] = src + src_pitch * 2;
99 x = 0, y = 0;
101 if (PixelsPerMask == 2) {
102 unsigned short *sbp;
103 sbp = (unsigned short*)src_line[0];
104 color[0] = *sbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0];
105 color[4] = color[0]; color[5] = color[0]; color[6] = *(sbp + 1); color[7] = *(sbp + 2);
106 sbp = (unsigned short*)src_line[2];
107 color[8] = *sbp; color[9] = color[8]; color[10] = *(sbp + 1); color[11] = *(sbp + 2);
108 sbp = (unsigned short*)src_line[3];
109 color[12] = *sbp; color[13] = color[12]; color[14] = *(sbp + 1); color[15] = *(sbp + 2);
111 else {
112 uint32_t *lbp;
113 lbp = (uint32_t*)src_line[0];
114 color[0] = *lbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0];
115 color[4] = color[0]; color[5] = color[0]; color[6] = *(lbp + 1); color[7] = *(lbp + 2);
116 lbp = (uint32_t*)src_line[2];
117 color[8] = *lbp; color[9] = color[8]; color[10] = *(lbp + 1); color[11] = *(lbp + 2);
118 lbp = (uint32_t*)src_line[3];
119 color[12] = *lbp; color[13] = color[12]; color[14] = *(lbp + 1); color[15] = *(lbp + 2);
122 for (y = 0; y < height; y++) {
124 dst_line[0] = dst + dst_pitch*2*y;
125 dst_line[1] = dst + dst_pitch*(2*y+1);
127 /* Todo: x = width - 2, x = width - 1 */
129 for (x = 0; x < width; x++) {
130 uint32_t product1a, product1b, product2a, product2b;
132 //--------------------------------------- B0 B1 B2 B3 0 1 2 3
133 // 4 5* 6 S2 -> 4 5* 6 7
134 // 1 2 3 S1 8 9 10 11
135 // A0 A1 A2 A3 12 13 14 15
136 //--------------------------------------
137 if (color[9] == color[6] && color[5] != color[10]) {
138 product2b = color[9];
139 product1b = product2b;
141 else if (color[5] == color[10] && color[9] != color[6]) {
142 product2b = color[5];
143 product1b = product2b;
145 else if (color[5] == color[10] && color[9] == color[6]) {
146 int r = 0;
148 r += GET_RESULT(color[6], color[5], color[8], color[13]);
149 r += GET_RESULT(color[6], color[5], color[4], color[1]);
150 r += GET_RESULT(color[6], color[5], color[14], color[11]);
151 r += GET_RESULT(color[6], color[5], color[2], color[7]);
153 if (r > 0)
154 product1b = color[6];
155 else if (r < 0)
156 product1b = color[5];
157 else
158 product1b = INTERPOLATE(color[5], color[6]);
160 product2b = product1b;
163 else {
164 if (color[6] == color[10] && color[10] == color[13] && color[9] != color[14] && color[10] != color[12])
165 product2b = Q_INTERPOLATE(color[10], color[10], color[10], color[9]);
166 else if (color[5] == color[9] && color[9] == color[14] && color[13] != color[10] && color[9] != color[15])
167 product2b = Q_INTERPOLATE(color[9], color[9], color[9], color[10]);
168 else
169 product2b = INTERPOLATE(color[9], color[10]);
171 if (color[6] == color[10] && color[6] == color[1] && color[5] != color[2] && color[6] != color[0])
172 product1b = Q_INTERPOLATE(color[6], color[6], color[6], color[5]);
173 else if (color[5] == color[9] && color[5] == color[2] && color[1] != color[6] && color[5] != color[3])
174 product1b = Q_INTERPOLATE(color[6], color[5], color[5], color[5]);
175 else
176 product1b = INTERPOLATE(color[5], color[6]);
179 if (color[5] == color[10] && color[9] != color[6] && color[4] == color[5] && color[5] != color[14])
180 product2a = INTERPOLATE(color[9], color[5]);
181 else if (color[5] == color[8] && color[6] == color[5] && color[4] != color[9] && color[5] != color[12])
182 product2a = INTERPOLATE(color[9], color[5]);
183 else
184 product2a = color[9];
186 if (color[9] == color[6] && color[5] != color[10] && color[8] == color[9] && color[9] != color[2])
187 product1a = INTERPOLATE(color[9], color[5]);
188 else if (color[4] == color[9] && color[10] == color[9] && color[8] != color[5] && color[9] != color[0])
189 product1a = INTERPOLATE(color[9], color[5]);
190 else
191 product1a = color[5];
193 if (PixelsPerMask == 2) {
194 *((uint32_t *) (&dst_line[0][x * 4])) = product1a | (product1b << 16);
195 *((uint32_t *) (&dst_line[1][x * 4])) = product2a | (product2b << 16);
197 else {
198 *((uint32_t *) (&dst_line[0][x * 8])) = product1a;
199 *((uint32_t *) (&dst_line[0][x * 8 + 4])) = product1b;
200 *((uint32_t *) (&dst_line[1][x * 8])) = product2a;
201 *((uint32_t *) (&dst_line[1][x * 8 + 4])) = product2b;
204 /* Move color matrix forward */
205 color[0] = color[1]; color[4] = color[5]; color[8] = color[9]; color[12] = color[13];
206 color[1] = color[2]; color[5] = color[6]; color[9] = color[10]; color[13] = color[14];
207 color[2] = color[3]; color[6] = color[7]; color[10] = color[11]; color[14] = color[15];
209 if (x < width - 3) {
210 x += 3;
211 if (PixelsPerMask == 2) {
212 color[3] = *(((unsigned short*)src_line[0]) + x);
213 color[7] = *(((unsigned short*)src_line[1]) + x);
214 color[11] = *(((unsigned short*)src_line[2]) + x);
215 color[15] = *(((unsigned short*)src_line[3]) + x);
217 else {
218 color[3] = *(((uint32_t*)src_line[0]) + x);
219 color[7] = *(((uint32_t*)src_line[1]) + x);
220 color[11] = *(((uint32_t*)src_line[2]) + x);
221 color[15] = *(((uint32_t*)src_line[3]) + x);
223 x -= 3;
227 /* We're done with one line, so we shift the source lines up */
228 src_line[0] = src_line[1];
229 src_line[1] = src_line[2];
230 src_line[2] = src_line[3];
232 /* Read next line */
233 if (y + 3 >= height)
234 src_line[3] = src_line[2];
235 else
236 src_line[3] = src_line[2] + src_pitch;
238 /* Then shift the color matrix up */
239 if (PixelsPerMask == 2) {
240 unsigned short *sbp;
241 sbp = (unsigned short*)src_line[0];
242 color[0] = *sbp; color[1] = color[0]; color[2] = *(sbp + 1); color[3] = *(sbp + 2);
243 sbp = (unsigned short*)src_line[1];
244 color[4] = *sbp; color[5] = color[4]; color[6] = *(sbp + 1); color[7] = *(sbp + 2);
245 sbp = (unsigned short*)src_line[2];
246 color[8] = *sbp; color[9] = color[9]; color[10] = *(sbp + 1); color[11] = *(sbp + 2);
247 sbp = (unsigned short*)src_line[3];
248 color[12] = *sbp; color[13] = color[12]; color[14] = *(sbp + 1); color[15] = *(sbp + 2);
250 else {
251 uint32_t *lbp;
252 lbp = (uint32_t*)src_line[0];
253 color[0] = *lbp; color[1] = color[0]; color[2] = *(lbp + 1); color[3] = *(lbp + 2);
254 lbp = (uint32_t*)src_line[1];
255 color[4] = *lbp; color[5] = color[4]; color[6] = *(lbp + 1); color[7] = *(lbp + 2);
256 lbp = (uint32_t*)src_line[2];
257 color[8] = *lbp; color[9] = color[9]; color[10] = *(lbp + 1); color[11] = *(lbp + 2);
258 lbp = (uint32_t*)src_line[3];
259 color[12] = *lbp; color[13] = color[12]; color[14] = *(lbp + 1); color[15] = *(lbp + 2);
262 } // y loop
267 //===========================================================================//
269 static int config(struct vf_instance_s* vf,
270 int width, int height, int d_width, int d_height,
271 unsigned int flags, unsigned int outfmt){
273 Init_2xSaI(outfmt&255);
275 return vf_next_config(vf,2*width,2*height,2*d_width,2*d_height,flags,outfmt);
278 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){
279 mp_image_t *dmpi;
281 // hope we'll get DR buffer:
282 dmpi=vf_get_image(vf->next,mpi->imgfmt,
283 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
284 2*mpi->w, 2*mpi->h);
286 Super2xSaI_ex(mpi->planes[0], mpi->stride[0],
287 dmpi->planes[0], dmpi->stride[0],
288 mpi->w, mpi->h, mpi->bpp/8);
290 return vf_next_put_image(vf,dmpi, pts);
293 //===========================================================================//
295 static int query_format(struct vf_instance_s* vf, unsigned int fmt){
296 switch(fmt){
297 // case IMGFMT_BGR15:
298 // case IMGFMT_BGR16:
299 case IMGFMT_BGR32:
300 return vf_next_query_format(vf,fmt);
302 return 0;
305 static int open(vf_instance_t *vf, char* args){
306 vf->config=config;
307 vf->put_image=put_image;
308 vf->query_format=query_format;
309 return 1;
312 const vf_info_t vf_info_2xsai = {
313 "2xSai BGR bitmap 2x scaler",
314 "2xsai",
315 "A'rpi",
316 "http://elektron.its.tudelft.nl/~dalikifa/",
317 open,
318 NULL
321 //===========================================================================//