• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavfilter/libmpcodecs/vf_2xsai.c

Go to the documentation of this file.
00001 /*
00002  * This file is part of MPlayer.
00003  *
00004  * MPlayer is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * MPlayer is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License along
00015  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
00016  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00017  */
00018 
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <inttypes.h>
00023 
00024 #include "config.h"
00025 #include "mp_msg.h"
00026 
00027 #include "img_format.h"
00028 #include "mp_image.h"
00029 #include "vf.h"
00030 
00031 //===========================================================================//
00032 
00033 /* FIXME: these all belong in the context, not as globals! */
00034 
00035 static uint32_t colorMask = 0xF7DEF7DE;
00036 static uint32_t lowPixelMask = 0x08210821;
00037 static uint32_t qcolorMask = 0xE79CE79C;
00038 static uint32_t qlowpixelMask = 0x18631863;
00039 static uint32_t redblueMask = 0xF81F;
00040 static uint32_t greenMask = 0x7E0;
00041 static int PixelsPerMask = 2;
00042 
00043 #define makecol(r,g,b) (r+(g<<8)+(b<<16))
00044 #define makecol_depth(d,r,g,b) (r+(g<<8)+(b<<16))
00045 
00046 static int Init_2xSaI(int d)
00047 {
00048 
00049         int minr = 0, ming = 0, minb = 0;
00050         int i;
00051 
00052 //        if (d != 15 && d != 16 && d != 24 && d != 32)
00053 //                return -1;
00054 
00055         /* Get lowest color bit */
00056         for (i = 0; i < 255; i++) {
00057                 if (!minr)
00058                         minr = makecol(i, 0, 0);
00059                 if (!ming)
00060                         ming = makecol(0, i, 0);
00061                 if (!minb)
00062                         minb = makecol(0, 0, i);
00063         }
00064 
00065         colorMask = (makecol_depth(d, 255, 0, 0) - minr) | (makecol_depth(d, 0, 255, 0) - ming) | (makecol_depth(d, 0, 0, 255) - minb);
00066         lowPixelMask = minr | ming | minb;
00067         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);
00068         qlowpixelMask = (minr * 3) | (ming * 3) | (minb * 3);
00069         redblueMask = makecol_depth(d, 255, 0, 255);
00070         greenMask = makecol_depth(d, 0, 255, 0);
00071 
00072         PixelsPerMask = (d <= 16) ? 2 : 1;
00073 
00074         if (PixelsPerMask == 2) {
00075                 colorMask |= (colorMask << 16);
00076                 qcolorMask |= (qcolorMask << 16);
00077                 lowPixelMask |= (lowPixelMask << 16);
00078                 qlowpixelMask |= (qlowpixelMask << 16);
00079         }
00080 
00081 //        TRACE("Color Mask:       0x%lX\n", colorMask);
00082 //        TRACE("Low Pixel Mask:   0x%lX\n", lowPixelMask);
00083 //        TRACE("QColor Mask:      0x%lX\n", qcolorMask);
00084 //        TRACE("QLow Pixel Mask:  0x%lX\n", qlowpixelMask);
00085 
00086         return 0;
00087 }
00088 
00089 
00090 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
00091 
00092 #define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask))
00093 
00094 #define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) \
00095         + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask)
00096 
00097 
00098 static void Super2xSaI_ex(uint8_t *src, uint32_t src_pitch,
00099                           uint8_t *dst, uint32_t dst_pitch,
00100                           uint32_t width, uint32_t height, int sbpp)
00101 {
00102 
00103         unsigned int x, y;
00104         uint32_t color[16];
00105         unsigned char *src_line[4];
00106 
00107         /* Point to the first 3 lines. */
00108         src_line[0] = src;
00109         src_line[1] = src;
00110         src_line[2] = src + src_pitch;
00111         src_line[3] = src + src_pitch * 2;
00112 
00113         x = 0, y = 0;
00114 
00115         if (PixelsPerMask == 2) {
00116                 unsigned short *sbp;
00117                 sbp = (unsigned short*)src_line[0];
00118                 color[0] = *sbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
00119                 color[4] = color[0];   color[5] = color[0];   color[6] = *(sbp + 1);  color[7] = *(sbp + 2);
00120                 sbp = (unsigned short*)src_line[2];
00121                 color[8] = *sbp;     color[9] = color[8];     color[10] = *(sbp + 1); color[11] = *(sbp + 2);
00122                 sbp = (unsigned short*)src_line[3];
00123                 color[12] = *sbp;    color[13] = color[12];   color[14] = *(sbp + 1); color[15] = *(sbp + 2);
00124         }
00125         else {
00126                 uint32_t *lbp;
00127                 lbp = (uint32_t*)src_line[0];
00128                 color[0] = *lbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
00129                 color[4] = color[0];   color[5] = color[0];   color[6] = *(lbp + 1);  color[7] = *(lbp + 2);
00130                 lbp = (uint32_t*)src_line[2];
00131                 color[8] = *lbp;     color[9] = color[8];     color[10] = *(lbp + 1); color[11] = *(lbp + 2);
00132                 lbp = (uint32_t*)src_line[3];
00133                 color[12] = *lbp;    color[13] = color[12];   color[14] = *(lbp + 1); color[15] = *(lbp + 2);
00134         }
00135 
00136         for (y = 0; y < height; y++) {
00137                 unsigned char *dst_line[2];
00138 
00139                 dst_line[0] = dst + dst_pitch*2*y;
00140                 dst_line[1] = dst + dst_pitch*(2*y+1);
00141 
00142                 /* Todo: x = width - 2, x = width - 1 */
00143 
00144                 for (x = 0; x < width; x++) {
00145                         uint32_t product1a, product1b, product2a, product2b;
00146 
00147 //---------------------------------------  B0 B1 B2 B3    0  1  2  3
00148 //                                         4  5* 6  S2 -> 4  5* 6  7
00149 //                                         1  2  3  S1    8  9 10 11
00150 //                                         A0 A1 A2 A3   12 13 14 15
00151 //--------------------------------------
00152                         if (color[9] == color[6] && color[5] != color[10]) {
00153                                 product2b = color[9];
00154                                 product1b = product2b;
00155                         }
00156                         else if (color[5] == color[10] && color[9] != color[6]) {
00157                                 product2b = color[5];
00158                                 product1b = product2b;
00159                         }
00160                         else if (color[5] == color[10] && color[9] == color[6]) {
00161                                 int r = 0;
00162 
00163                                 r += GET_RESULT(color[6], color[5], color[8], color[13]);
00164                                 r += GET_RESULT(color[6], color[5], color[4], color[1]);
00165                                 r += GET_RESULT(color[6], color[5], color[14], color[11]);
00166                                 r += GET_RESULT(color[6], color[5], color[2], color[7]);
00167 
00168                                 if (r > 0)
00169                                         product1b = color[6];
00170                                 else if (r < 0)
00171                                         product1b = color[5];
00172                                 else
00173                                         product1b = INTERPOLATE(color[5], color[6]);
00174 
00175                                 product2b = product1b;
00176 
00177                         }
00178                         else {
00179                                 if (color[6] == color[10] && color[10] == color[13] && color[9] != color[14] && color[10] != color[12])
00180                                         product2b = Q_INTERPOLATE(color[10], color[10], color[10], color[9]);
00181                                 else if (color[5] == color[9] && color[9] == color[14] && color[13] != color[10] && color[9] != color[15])
00182                                         product2b = Q_INTERPOLATE(color[9], color[9], color[9], color[10]);
00183                                 else
00184                                         product2b = INTERPOLATE(color[9], color[10]);
00185 
00186                                 if (color[6] == color[10] && color[6] == color[1] && color[5] != color[2] && color[6] != color[0])
00187                                         product1b = Q_INTERPOLATE(color[6], color[6], color[6], color[5]);
00188                                 else if (color[5] == color[9] && color[5] == color[2] && color[1] != color[6] && color[5] != color[3])
00189                                         product1b = Q_INTERPOLATE(color[6], color[5], color[5], color[5]);
00190                                 else
00191                                         product1b = INTERPOLATE(color[5], color[6]);
00192                         }
00193 
00194                         if (color[5] == color[10] && color[9] != color[6] && color[4] == color[5] && color[5] != color[14])
00195                                 product2a = INTERPOLATE(color[9], color[5]);
00196                         else if (color[5] == color[8] && color[6] == color[5] && color[4] != color[9] && color[5] != color[12])
00197                                 product2a = INTERPOLATE(color[9], color[5]);
00198                         else
00199                                 product2a = color[9];
00200 
00201                         if (color[9] == color[6] && color[5] != color[10] && color[8] == color[9] && color[9] != color[2])
00202                                 product1a = INTERPOLATE(color[9], color[5]);
00203                         else if (color[4] == color[9] && color[10] == color[9] && color[8] != color[5] && color[9] != color[0])
00204                                 product1a = INTERPOLATE(color[9], color[5]);
00205                         else
00206                                 product1a = color[5];
00207 
00208                         if (PixelsPerMask == 2) {
00209                                 *((uint32_t *) (&dst_line[0][x * 4])) = product1a | (product1b << 16);
00210                                 *((uint32_t *) (&dst_line[1][x * 4])) = product2a | (product2b << 16);
00211                         }
00212                         else {
00213                                 *((uint32_t *) (&dst_line[0][x * 8])) = product1a;
00214                                 *((uint32_t *) (&dst_line[0][x * 8 + 4])) = product1b;
00215                                 *((uint32_t *) (&dst_line[1][x * 8])) = product2a;
00216                                 *((uint32_t *) (&dst_line[1][x * 8 + 4])) = product2b;
00217                         }
00218 
00219                         /* Move color matrix forward */
00220                         color[0] = color[1]; color[4] = color[5]; color[8] = color[9];   color[12] = color[13];
00221                         color[1] = color[2]; color[5] = color[6]; color[9] = color[10];  color[13] = color[14];
00222                         color[2] = color[3]; color[6] = color[7]; color[10] = color[11]; color[14] = color[15];
00223 
00224                         if (x < width - 3) {
00225                                 x += 3;
00226                                 if (PixelsPerMask == 2) {
00227                                         color[3] = *(((unsigned short*)src_line[0]) + x);
00228                                         color[7] = *(((unsigned short*)src_line[1]) + x);
00229                                         color[11] = *(((unsigned short*)src_line[2]) + x);
00230                                         color[15] = *(((unsigned short*)src_line[3]) + x);
00231                                 }
00232                                 else {
00233                                         color[3] = *(((uint32_t*)src_line[0]) + x);
00234                                         color[7] = *(((uint32_t*)src_line[1]) + x);
00235                                         color[11] = *(((uint32_t*)src_line[2]) + x);
00236                                         color[15] = *(((uint32_t*)src_line[3]) + x);
00237                                 }
00238                                 x -= 3;
00239                         }
00240                 }
00241 
00242                 /* We're done with one line, so we shift the source lines up */
00243                 src_line[0] = src_line[1];
00244                 src_line[1] = src_line[2];
00245                 src_line[2] = src_line[3];
00246 
00247                 /* Read next line */
00248                 if (y + 3 >= height)
00249                         src_line[3] = src_line[2];
00250                 else
00251                         src_line[3] = src_line[2] + src_pitch;
00252 
00253                 /* Then shift the color matrix up */
00254                 if (PixelsPerMask == 2) {
00255                         unsigned short *sbp;
00256                         sbp = (unsigned short*)src_line[0];
00257                         color[0] = *sbp;     color[1] = color[0];    color[2] = *(sbp + 1);  color[3] = *(sbp + 2);
00258                         sbp = (unsigned short*)src_line[1];
00259                         color[4] = *sbp;     color[5] = color[4];    color[6] = *(sbp + 1);  color[7] = *(sbp + 2);
00260                         sbp = (unsigned short*)src_line[2];
00261                         color[8] = *sbp;     color[9] = color[9];    color[10] = *(sbp + 1); color[11] = *(sbp + 2);
00262                         sbp = (unsigned short*)src_line[3];
00263                         color[12] = *sbp;    color[13] = color[12];  color[14] = *(sbp + 1); color[15] = *(sbp + 2);
00264                 }
00265                 else {
00266                         uint32_t *lbp;
00267                         lbp = (uint32_t*)src_line[0];
00268                         color[0] = *lbp;     color[1] = color[0];    color[2] = *(lbp + 1);  color[3] = *(lbp + 2);
00269                         lbp = (uint32_t*)src_line[1];
00270                         color[4] = *lbp;     color[5] = color[4];    color[6] = *(lbp + 1);  color[7] = *(lbp + 2);
00271                         lbp = (uint32_t*)src_line[2];
00272                         color[8] = *lbp;     color[9] = color[9];    color[10] = *(lbp + 1); color[11] = *(lbp + 2);
00273                         lbp = (uint32_t*)src_line[3];
00274                         color[12] = *lbp;    color[13] = color[12];  color[14] = *(lbp + 1); color[15] = *(lbp + 2);
00275                 }
00276 
00277         } // y loop
00278 
00279 }
00280 
00281 
00282 //===========================================================================//
00283 
00284 static int config(struct vf_instance *vf,
00285         int width, int height, int d_width, int d_height,
00286         unsigned int flags, unsigned int outfmt){
00287 
00288     Init_2xSaI(outfmt&255);
00289 
00290     return vf_next_config(vf,2*width,2*height,2*d_width,2*d_height,flags,outfmt);
00291 }
00292 
00293 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
00294     mp_image_t *dmpi;
00295 
00296     // hope we'll get DR buffer:
00297     dmpi=vf_get_image(vf->next,mpi->imgfmt,
00298         MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
00299         2*mpi->w, 2*mpi->h);
00300 
00301     Super2xSaI_ex(mpi->planes[0], mpi->stride[0],
00302                   dmpi->planes[0], dmpi->stride[0],
00303                   mpi->w, mpi->h, mpi->bpp/8);
00304 
00305     return vf_next_put_image(vf,dmpi, pts);
00306 }
00307 
00308 //===========================================================================//
00309 
00310 static int query_format(struct vf_instance *vf, unsigned int fmt){
00311     switch(fmt){
00312 //    case IMGFMT_BGR15:
00313 //    case IMGFMT_BGR16:
00314     case IMGFMT_BGR32:
00315         return vf_next_query_format(vf,fmt);
00316     }
00317     return 0;
00318 }
00319 
00320 static int vf_open(vf_instance_t *vf, char *args){
00321     vf->config=config;
00322     vf->put_image=put_image;
00323     vf->query_format=query_format;
00324     return 1;
00325 }
00326 
00327 const vf_info_t vf_info_2xsai = {
00328     "2xSai BGR bitmap 2x scaler",
00329     "2xsai",
00330     "A'rpi",
00331     "http://elektron.its.tudelft.nl/~dalikifa/",
00332     vf_open,
00333     NULL
00334 };
00335 
00336 //===========================================================================//
Generated on Fri Feb 1 2013 14:34:48 for FFmpeg by doxygen 1.7.1