qtmobility/plugins/multimedia/v4l/camera/cameraformatconverter.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 5 453da2cfceef
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "cameraformatconverter.h"
       
    43 #include <QDebug>
       
    44 
       
    45 /*
       
    46     Create a format converter
       
    47 */
       
    48 
       
    49 CameraFormatConverter* CameraFormatConverter::createFormatConverter(QVideoFrame::PixelFormat format, int width, int height)
       
    50 {
       
    51     if(format == QVideoFrame::Format_YUYV)
       
    52         return new YUVConverter(format,width,height);
       
    53     else if(format == QVideoFrame::Format_UYVY)
       
    54         return new YUVConverter(format,width,height);
       
    55     else if(format == QVideoFrame::Format_YUV420P)
       
    56         return new YUVConverter(format,width,height);
       
    57     else
       
    58         return new NullConverter;
       
    59 }
       
    60 
       
    61 void CameraFormatConverter::releaseFormatConverter(CameraFormatConverter* converter)
       
    62 {
       
    63     delete converter;
       
    64 }
       
    65 
       
    66 
       
    67 // Null Converter
       
    68 unsigned char* NullConverter::convert(unsigned char* src, int len)
       
    69 {
       
    70     Q_UNUSED(len)
       
    71     return src;
       
    72 }
       
    73 
       
    74 QList<QVideoFrame::PixelFormat> CameraFormatConverter::supportedFormats()
       
    75 {
       
    76     QList<QVideoFrame::PixelFormat> list;
       
    77     list << QVideoFrame::Format_RGB24 << QVideoFrame::Format_YUYV << QVideoFrame::Format_RGB32
       
    78         << QVideoFrame::Format_UYVY << QVideoFrame::Format_YUV420P << QVideoFrame::Format_RGB555;
       
    79     return list;
       
    80 }
       
    81 
       
    82 // YUV
       
    83 YUVConverter::YUVConverter(QVideoFrame::PixelFormat type,int width, int height):
       
    84     m_type(type),
       
    85     m_width(width),
       
    86     m_height(height)
       
    87 {
       
    88     m_buf = new unsigned char[width * height * 2];
       
    89 
       
    90     if (m_type == QVideoFrame::Format_YUYV) {
       
    91         // For YUY2 format use these to match (Y0-U0-Y1-V0)
       
    92         m_y1i=0;
       
    93         m_ui =1;
       
    94         m_y2i=2;
       
    95         m_vi =3;
       
    96     } else if(m_type == QVideoFrame::Format_UYVY) {
       
    97         m_y1i=1;
       
    98         m_ui =0;
       
    99         m_y2i=3;
       
   100         m_vi =2;
       
   101     }
       
   102 }
       
   103 
       
   104 YUVConverter::~YUVConverter()
       
   105 {
       
   106     delete [] m_buf;
       
   107 }
       
   108 
       
   109 
       
   110 static const signed short redAdjust[] = {
       
   111 -161,-160,-159,-158,-157,-156,-155,-153,
       
   112 -152,-151,-150,-149,-148,-147,-145,-144,
       
   113 -143,-142,-141,-140,-139,-137,-136,-135,
       
   114 -134,-133,-132,-131,-129,-128,-127,-126,
       
   115 -125,-124,-123,-122,-120,-119,-118,-117,
       
   116 -116,-115,-114,-112,-111,-110,-109,-108,
       
   117 -107,-106,-104,-103,-102,-101,-100, -99,
       
   118  -98, -96, -95, -94, -93, -92, -91, -90,
       
   119  -88, -87, -86, -85, -84, -83, -82, -80,
       
   120  -79, -78, -77, -76, -75, -74, -72, -71,
       
   121  -70, -69, -68, -67, -66, -65, -63, -62,
       
   122  -61, -60, -59, -58, -57, -55, -54, -53,
       
   123  -52, -51, -50, -49, -47, -46, -45, -44,
       
   124  -43, -42, -41, -39, -38, -37, -36, -35,
       
   125  -34, -33, -31, -30, -29, -28, -27, -26,
       
   126  -25, -23, -22, -21, -20, -19, -18, -17,
       
   127  -16, -14, -13, -12, -11, -10,  -9,  -8,
       
   128   -6,  -5,  -4,  -3,  -2,  -1,   0,   1,
       
   129    2,   3,   4,   5,   6,   7,   9,  10,
       
   130   11,  12,  13,  14,  15,  17,  18,  19,
       
   131   20,  21,  22,  23,  25,  26,  27,  28,
       
   132   29,  30,  31,  33,  34,  35,  36,  37,
       
   133   38,  39,  40,  42,  43,  44,  45,  46,
       
   134   47,  48,  50,  51,  52,  53,  54,  55,
       
   135   56,  58,  59,  60,  61,  62,  63,  64,
       
   136   66,  67,  68,  69,  70,  71,  72,  74,
       
   137   75,  76,  77,  78,  79,  80,  82,  83,
       
   138   84,  85,  86,  87,  88,  90,  91,  92,
       
   139   93,  94,  95,  96,  97,  99, 100, 101,
       
   140  102, 103, 104, 105, 107, 108, 109, 110,
       
   141  111, 112, 113, 115, 116, 117, 118, 119,
       
   142  120, 121, 123, 124, 125, 126, 127, 128,
       
   143 };
       
   144 
       
   145 static const signed short greenAdjust1[] = {
       
   146   34,  34,  33,  33,  32,  32,  32,  31,
       
   147   31,  30,  30,  30,  29,  29,  28,  28,
       
   148   28,  27,  27,  27,  26,  26,  25,  25,
       
   149   25,  24,  24,  23,  23,  23,  22,  22,
       
   150   21,  21,  21,  20,  20,  19,  19,  19,
       
   151   18,  18,  17,  17,  17,  16,  16,  15,
       
   152   15,  15,  14,  14,  13,  13,  13,  12,
       
   153   12,  12,  11,  11,  10,  10,  10,   9,
       
   154    9,   8,   8,   8,   7,   7,   6,   6,
       
   155    6,   5,   5,   4,   4,   4,   3,   3,
       
   156    2,   2,   2,   1,   1,   0,   0,   0,
       
   157    0,   0,  -1,  -1,  -1,  -2,  -2,  -2,
       
   158   -3,  -3,  -4,  -4,  -4,  -5,  -5,  -6,
       
   159   -6,  -6,  -7,  -7,  -8,  -8,  -8,  -9,
       
   160   -9, -10, -10, -10, -11, -11, -12, -12,
       
   161  -12, -13, -13, -14, -14, -14, -15, -15,
       
   162  -16, -16, -16, -17, -17, -17, -18, -18,
       
   163  -19, -19, -19, -20, -20, -21, -21, -21,
       
   164  -22, -22, -23, -23, -23, -24, -24, -25,
       
   165  -25, -25, -26, -26, -27, -27, -27, -28,
       
   166  -28, -29, -29, -29, -30, -30, -30, -31,
       
   167  -31, -32, -32, -32, -33, -33, -34, -34,
       
   168  -34, -35, -35, -36, -36, -36, -37, -37,
       
   169  -38, -38, -38, -39, -39, -40, -40, -40,
       
   170  -41, -41, -42, -42, -42, -43, -43, -44,
       
   171  -44, -44, -45, -45, -45, -46, -46, -47,
       
   172  -47, -47, -48, -48, -49, -49, -49, -50,
       
   173  -50, -51, -51, -51, -52, -52, -53, -53,
       
   174  -53, -54, -54, -55, -55, -55, -56, -56,
       
   175  -57, -57, -57, -58, -58, -59, -59, -59,
       
   176  -60, -60, -60, -61, -61, -62, -62, -62,
       
   177  -63, -63, -64, -64, -64, -65, -65, -66,
       
   178 };
       
   179 
       
   180 static const signed short greenAdjust2[] = {
       
   181   74,  73,  73,  72,  71,  71,  70,  70,
       
   182   69,  69,  68,  67,  67,  66,  66,  65,
       
   183   65,  64,  63,  63,  62,  62,  61,  60,
       
   184   60,  59,  59,  58,  58,  57,  56,  56,
       
   185   55,  55,  54,  53,  53,  52,  52,  51,
       
   186   51,  50,  49,  49,  48,  48,  47,  47,
       
   187   46,  45,  45,  44,  44,  43,  42,  42,
       
   188   41,  41,  40,  40,  39,  38,  38,  37,
       
   189   37,  36,  35,  35,  34,  34,  33,  33,
       
   190   32,  31,  31,  30,  30,  29,  29,  28,
       
   191   27,  27,  26,  26,  25,  24,  24,  23,
       
   192   23,  22,  22,  21,  20,  20,  19,  19,
       
   193   18,  17,  17,  16,  16,  15,  15,  14,
       
   194   13,  13,  12,  12,  11,  11,  10,   9,
       
   195    9,   8,   8,   7,   6,   6,   5,   5,
       
   196    4,   4,   3,   2,   2,   1,   1,   0,
       
   197    0,   0,  -1,  -1,  -2,  -2,  -3,  -4,
       
   198   -4,  -5,  -5,  -6,  -6,  -7,  -8,  -8,
       
   199   -9,  -9, -10, -11, -11, -12, -12, -13,
       
   200  -13, -14, -15, -15, -16, -16, -17, -17,
       
   201  -18, -19, -19, -20, -20, -21, -22, -22,
       
   202  -23, -23, -24, -24, -25, -26, -26, -27,
       
   203  -27, -28, -29, -29, -30, -30, -31, -31,
       
   204  -32, -33, -33, -34, -34, -35, -35, -36,
       
   205  -37, -37, -38, -38, -39, -40, -40, -41,
       
   206  -41, -42, -42, -43, -44, -44, -45, -45,
       
   207  -46, -47, -47, -48, -48, -49, -49, -50,
       
   208  -51, -51, -52, -52, -53, -53, -54, -55,
       
   209  -55, -56, -56, -57, -58, -58, -59, -59,
       
   210  -60, -60, -61, -62, -62, -63, -63, -64,
       
   211  -65, -65, -66, -66, -67, -67, -68, -69,
       
   212  -69, -70, -70, -71, -71, -72, -73, -73,
       
   213 };
       
   214 
       
   215 static const signed short blueAdjust[] = {
       
   216 -276,-274,-272,-270,-267,-265,-263,-261,
       
   217 -259,-257,-255,-253,-251,-249,-247,-245,
       
   218 -243,-241,-239,-237,-235,-233,-231,-229,
       
   219 -227,-225,-223,-221,-219,-217,-215,-213,
       
   220 -211,-209,-207,-204,-202,-200,-198,-196,
       
   221 -194,-192,-190,-188,-186,-184,-182,-180,
       
   222 -178,-176,-174,-172,-170,-168,-166,-164,
       
   223 -162,-160,-158,-156,-154,-152,-150,-148,
       
   224 -146,-144,-141,-139,-137,-135,-133,-131,
       
   225 -129,-127,-125,-123,-121,-119,-117,-115,
       
   226 -113,-111,-109,-107,-105,-103,-101, -99,
       
   227  -97, -95, -93, -91, -89, -87, -85, -83,
       
   228  -81, -78, -76, -74, -72, -70, -68, -66,
       
   229  -64, -62, -60, -58, -56, -54, -52, -50,
       
   230  -48, -46, -44, -42, -40, -38, -36, -34,
       
   231  -32, -30, -28, -26, -24, -22, -20, -18,
       
   232  -16, -13, -11,  -9,  -7,  -5,  -3,  -1,
       
   233    0,   2,   4,   6,   8,  10,  12,  14,
       
   234   16,  18,  20,  22,  24,  26,  28,  30,
       
   235   32,  34,  36,  38,  40,  42,  44,  46,
       
   236   49,  51,  53,  55,  57,  59,  61,  63,
       
   237   65,  67,  69,  71,  73,  75,  77,  79,
       
   238   81,  83,  85,  87,  89,  91,  93,  95,
       
   239   97,  99, 101, 103, 105, 107, 109, 112,
       
   240  114, 116, 118, 120, 122, 124, 126, 128,
       
   241  130, 132, 134, 136, 138, 140, 142, 144,
       
   242  146, 148, 150, 152, 154, 156, 158, 160,
       
   243  162, 164, 166, 168, 170, 172, 175, 177,
       
   244  179, 181, 183, 185, 187, 189, 191, 193,
       
   245  195, 197, 199, 201, 203, 205, 207, 209,
       
   246  211, 213, 215, 217, 219, 221, 223, 225,
       
   247  227, 229, 231, 233, 235, 238, 240, 242,
       
   248 };
       
   249 
       
   250 
       
   251 
       
   252 #define CLAMP(x) x < 0 ? 0 : x & 0xff
       
   253 
       
   254 inline void yuv2rgb565(int y, int u, int v, quint16 *rgb)
       
   255 {
       
   256     register int r, g, b;
       
   257 
       
   258     r = y + redAdjust[v];
       
   259     g = y + greenAdjust1[u] + greenAdjust2[v];
       
   260     b = y + blueAdjust[u];
       
   261 
       
   262 #if 0
       
   263     y -= 16;
       
   264     u -= 128;
       
   265     v -= 128;
       
   266     r = y + 1.13983*v;
       
   267     g = y + 0.39465*u - 0.58060*v;
       
   268     b = y + 2.03211*u;
       
   269 #endif
       
   270 
       
   271     r = CLAMP(r);
       
   272     g = CLAMP(g);
       
   273     b = CLAMP(b);
       
   274 
       
   275     *rgb = (quint16)(((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3));
       
   276 }
       
   277 
       
   278 inline void yuv2rgb24(int y, int u, int v, quint32 *rgb)
       
   279 {
       
   280     register int r, g, b;
       
   281 
       
   282     r = y + redAdjust[v];
       
   283     g = y + greenAdjust1[u] + greenAdjust2[v];
       
   284     b = y + blueAdjust[u];
       
   285 
       
   286     r = CLAMP(r);
       
   287     g = CLAMP(g);
       
   288     b = CLAMP(b);
       
   289 
       
   290     *rgb = ((r<<24)|(g<<16) | b) | 0xff000000 ;
       
   291 }
       
   292 
       
   293 #define yuv2rgb(a,b,c,d) yuv2rgb565(a,b,c,d)
       
   294 
       
   295 unsigned char* YUVConverter::convert(unsigned char* src, int len)
       
   296 {
       
   297     quint16* dest = (quint16*)m_buf;
       
   298     unsigned char *buf = src;
       
   299     int size = (m_width * m_height) >> 1;
       
   300 
       
   301 
       
   302 #define CONV  \
       
   303 {\
       
   304     register int u = buf[m_ui];\
       
   305     register int v = buf[m_vi];\
       
   306     yuv2rgb(buf[m_y1i], u, v, dest);\
       
   307     yuv2rgb(buf[m_y2i], u, v, ++dest);\
       
   308     dest++;\
       
   309     buf+= 4;\
       
   310 }
       
   311     if (m_type != QVideoFrame::Format_YUV420P) {
       
   312         register int n = (size + 7) / 8;
       
   313         switch(size & 7)
       
   314         {
       
   315             case 0: do {CONV
       
   316             case 7:     CONV
       
   317             case 6:     CONV
       
   318             case 5:     CONV
       
   319             case 4:     CONV
       
   320             case 3:     CONV
       
   321             case 2:     CONV
       
   322             case 1:     CONV
       
   323                 } while(--n);
       
   324 	}
       
   325     } else {
       
   326         // for 320x240 use 353x288, only works for this res!!
       
   327 	int w = m_width;
       
   328 	int h = m_height;
       
   329         int Ysize = w * h;
       
   330 	if(len == Ysize+Ysize/4+Ysize/4) {
       
   331             for(int y=0;y<m_height;y++) {
       
   332 	        for(int x=0;x<m_width;x++) {
       
   333 	            int yy = (int)buf[y*w+x];
       
   334 		    int u = (int)buf[(y/2)*(w/2)+x/2+Ysize];
       
   335                     int v = (int)buf[(y/2)*(w/2)+x/2+Ysize+Ysize/4];
       
   336 		    yuv2rgb565(yy,u,v,dest);
       
   337 		    dest++;
       
   338 		}
       
   339 	    }
       
   340 	} else {
       
   341 	    qWarning("buffer provided doesn't match expected size!!!");
       
   342 	}
       
   343     }
       
   344 
       
   345     return m_buf;
       
   346 
       
   347 }
       
   348 
       
   349 /*
       
   350  * convert ROUTINE TAKEN FROM:
       
   351  *
       
   352  * Sonix SN9C101 based webcam basic I/F routines
       
   353  * Copyright (C) 2004 Takafumi Mizuno <taka-qce@ls-a.jp>
       
   354  *
       
   355  * Redistribution and use in source and binary forms, with or without
       
   356  * modification, are permitted provided that the following conditions
       
   357  * are met:
       
   358  * 1. Redistributions of source code must retain the above copyright
       
   359  *    notice, this list of conditions and the following disclaimer.
       
   360  * 2. Redistributions in binary form must reproduce the above copyright
       
   361  *    notice, this list of conditions and the following disclaimer in the
       
   362  *    documentation and/or other materials provided with the distribution.
       
   363  *
       
   364  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
       
   365  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
   366  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
   367  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
       
   368  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
       
   369  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
       
   370  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
   371  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
       
   372  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
       
   373  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
       
   374  * SUCH DAMAGE.
       
   375  */
       
   376 
       
   377 BayerConverter::BayerConverter(int width, int height):
       
   378     m_width(width),
       
   379     m_height(height)
       
   380 {
       
   381     m_buf = new unsigned char[width * height * 4];  // 4 = 32bpp / 8 bpb
       
   382 }
       
   383 
       
   384 BayerConverter::~BayerConverter()
       
   385 {
       
   386     delete m_buf;
       
   387 }
       
   388 
       
   389 unsigned char* BayerConverter::convert(unsigned char* src, int len)
       
   390 {
       
   391     Q_UNUSED(len)
       
   392 
       
   393     int             size = m_width * m_height;
       
   394     unsigned long   *dst = (unsigned long*) m_buf;
       
   395 
       
   396     register unsigned long   dstVal;
       
   397 
       
   398     for (int i = 0; i < size; ++i)
       
   399     {
       
   400         dstVal = 0xFF000000;
       
   401 
       
   402         if ((i / m_width) % 2 == 0)
       
   403         {
       
   404             if (!(i & 1))
       
   405             {
       
   406                 /* B */
       
   407                 if ((i > m_width) && ((i % m_width) > 0) )
       
   408                 {
       
   409                     dstVal |= ((*(src-m_width-1)+*(src-m_width+1)+ *(src+m_width-1)+*(src+m_width + 1)) / 4) << 16 |
       
   410                               ((*(src-1)+*(src+1)+*(src+m_width)+*(src-m_width))/4) << 8 |
       
   411                               *src;
       
   412                 }
       
   413                 else
       
   414                 {
       
   415                     dstVal |= *(src + m_width + 1) << 16 |
       
   416                               (*(src + 1) + *(src + m_width)) / 2 << 8 |
       
   417                               *src;
       
   418                 }
       
   419             }
       
   420             else
       
   421             {
       
   422                 /* (B)G */
       
   423                 if ((i > m_width) && ((i % m_width) < (m_width - 1)))
       
   424                 {
       
   425                     dstVal |= (*(src+m_width)+*(src-m_width))/2 << 16 |
       
   426                               *src << 8 |
       
   427                               (*(src-1)+*(src+1))/2;
       
   428                 }
       
   429                 else
       
   430                 {
       
   431                     dstVal |= *(src+m_width) << 16 |
       
   432                               *src << 8 |
       
   433                               *(src - 1);
       
   434                 }
       
   435             }
       
   436         }
       
   437         else {
       
   438 
       
   439             if (!(i & 1))
       
   440             {
       
   441                 /* G(R) */
       
   442                 if ((i < (m_width * (m_height - 1))) && ((i % m_width) > 0) )
       
   443                 {
       
   444                     dstVal |= ((*(src - 1) + *(src + 1)) / 2) << 16 |
       
   445                               *src << 8 |
       
   446                               (*(src + m_width) + *(src - m_width)) / 2;
       
   447                 }
       
   448                 else
       
   449                 {
       
   450                     dstVal |= *(src + 1) << 16 |
       
   451                               *src << 8 |
       
   452                               *(src - m_width);
       
   453                 }
       
   454             }
       
   455             else
       
   456             {
       
   457                 /* R */
       
   458                 if (i < (m_width * (m_height - 1)) && ((i % m_width) < (m_width - 1)) )
       
   459                 {
       
   460                     dstVal |= *src << 16 |
       
   461                               (*(src-1)+*(src+1)+ *(src-m_width)+*(src+m_width))/4 << 8 |
       
   462                               (*(src-m_width-1)+*(src-m_width+1)+ *(src+m_width-1)+*(src+m_width+1))/4;
       
   463                 }
       
   464                 else
       
   465                 {
       
   466                     dstVal |= *src << 16 |
       
   467                               (*(src-1)+*(src-m_width))/2 << 8 |
       
   468                               *(src-m_width-1);
       
   469                 }
       
   470             }
       
   471         }
       
   472 
       
   473         *dst++ = dstVal;
       
   474             ++src;
       
   475     }
       
   476 
       
   477     return m_buf;
       
   478 }
       
   479 
       
   480