LCOV - code coverage report
Current view: top level - media/webrtc/signaling/src/common - YuvStamper.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 119 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       3             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #ifdef HAVE_NETINET_IN_H
       6             : #include <netinet/in.h>
       7             : #elif defined XP_WIN
       8             : #include <winsock2.h>
       9             : #endif
      10             : #include <string.h>
      11             : 
      12             : #include "nspr.h"
      13             : #include "YuvStamper.h"
      14             : #include "mozilla/Sprintf.h"
      15             : 
      16             : typedef uint32_t UINT4; //Needed for r_crc32() call
      17             : extern "C" {
      18             : #include "r_crc32.h"
      19             : }
      20             : 
      21             : namespace mozilla {
      22             : 
      23             : #define ON_5 0x20
      24             : #define ON_4 0x10
      25             : #define ON_3 0x08
      26             : #define ON_2 0x04
      27             : #define ON_1 0x02
      28             : #define ON_0 0x01
      29             : 
      30             : /*
      31             :   0, 0, 1, 1, 0, 0,
      32             :   0, 1, 0, 0, 1, 0,
      33             :   1, 0, 0, 0, 0, 1,
      34             :   1, 0, 0, 0, 0, 1,
      35             :   1, 0, 0, 0, 0, 1,
      36             :   0, 1, 0, 0, 1, 0,
      37             :   0, 0, 1, 1, 0, 0
      38             : */
      39             : static unsigned char DIGIT_0 [] =
      40             :   { ON_3 | ON_2,
      41             :     ON_4 | ON_1,
      42             :     ON_5 | ON_0,
      43             :     ON_5 | ON_0,
      44             :     ON_5 | ON_0,
      45             :     ON_4 | ON_1,
      46             :     ON_3 | ON_2
      47             :   };
      48             : 
      49             : /*
      50             :   0, 0, 0, 1, 0, 0,
      51             :   0, 0, 0, 1, 0, 0,
      52             :   0, 0, 0, 1, 0, 0,
      53             :   0, 0, 0, 1, 0, 0,
      54             :   0, 0, 0, 1, 0, 0,
      55             :   0, 0, 0, 1, 0, 0,
      56             :   0, 0, 0, 1, 0, 0,
      57             : */
      58             : static unsigned char DIGIT_1 [] =
      59             :   { ON_2,
      60             :     ON_2,
      61             :     ON_2,
      62             :     ON_2,
      63             :     ON_2,
      64             :     ON_2,
      65             :     ON_2
      66             :   };
      67             : 
      68             : /*
      69             :   1, 1, 1, 1, 1, 0,
      70             :   0, 0, 0, 0, 0, 1,
      71             :   0, 0, 0, 0, 0, 1,
      72             :   0, 1, 1, 1, 1, 0,
      73             :   1, 0, 0, 0, 0, 0,
      74             :   1, 0, 0, 0, 0, 0,
      75             :   0, 1, 1, 1, 1, 1,
      76             : */
      77             : static unsigned char DIGIT_2 [] =
      78             :   { ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
      79             :     ON_0,
      80             :     ON_0,
      81             :     ON_4 | ON_3 | ON_2 | ON_1,
      82             :     ON_5,
      83             :     ON_5,
      84             :     ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
      85             :   };
      86             : 
      87             : /*
      88             :   1, 1, 1, 1, 1, 0,
      89             :   0, 0, 0, 0, 0, 1,
      90             :   0, 0, 0, 0, 0, 1,
      91             :   0, 1, 1, 1, 1, 1,
      92             :   0, 0, 0, 0, 0, 1,
      93             :   0, 0, 0, 0, 0, 1,
      94             :   1, 1, 1, 1, 1, 0,
      95             : */
      96             : static unsigned char DIGIT_3 [] =
      97             :   { ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
      98             :     ON_0,
      99             :     ON_0,
     100             :     ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
     101             :     ON_0,
     102             :     ON_0,
     103             :     ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
     104             :   };
     105             : 
     106             : /*
     107             :   0, 1, 0, 0, 0, 1,
     108             :   0, 1, 0, 0, 0, 1,
     109             :   0, 1, 0, 0, 0, 1,
     110             :   0, 1, 1, 1, 1, 1,
     111             :   0, 0, 0, 0, 0, 1,
     112             :   0, 0, 0, 0, 0, 1,
     113             :   0, 0, 0, 0, 0, 1
     114             : */
     115             : static unsigned char DIGIT_4 [] =
     116             :   { ON_4 | ON_0,
     117             :     ON_4 | ON_0,
     118             :     ON_4 | ON_0,
     119             :     ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
     120             :     ON_0,
     121             :     ON_0,
     122             :     ON_0,
     123             :   };
     124             : 
     125             : /*
     126             :   0, 1, 1, 1, 1, 1,
     127             :   1, 0, 0, 0, 0, 0,
     128             :   1, 0, 0, 0, 0, 0,
     129             :   0, 1, 1, 1, 1, 0,
     130             :   0, 0, 0, 0, 0, 1,
     131             :   0, 0, 0, 0, 0, 1,
     132             :   1, 1, 1, 1, 1, 0,
     133             : */
     134             : static unsigned char DIGIT_5 [] =
     135             :   { ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
     136             :     ON_5,
     137             :     ON_5,
     138             :     ON_4 | ON_3 | ON_2 | ON_1,
     139             :     ON_0,
     140             :     ON_0,
     141             :     ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
     142             :   };
     143             : 
     144             : /*
     145             :   0, 1, 1, 1, 1, 1,
     146             :   1, 0, 0, 0, 0, 0,
     147             :   1, 0, 0, 0, 0, 0,
     148             :   1, 1, 1, 1, 1, 0,
     149             :   1, 0, 0, 0, 0, 1,
     150             :   1, 0, 0, 0, 0, 1,
     151             :   0, 1, 1, 1, 1, 0,
     152             : */
     153             : static unsigned char DIGIT_6 [] =
     154             :   { ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
     155             :     ON_5,
     156             :     ON_5,
     157             :     ON_4 | ON_3 | ON_2 | ON_1,
     158             :     ON_5 | ON_0,
     159             :     ON_5 | ON_0,
     160             :     ON_4 | ON_3 | ON_2 | ON_1,
     161             :   };
     162             : 
     163             : /*
     164             :   1, 1, 1, 1, 1, 1,
     165             :   0, 0, 0, 0, 0, 1,
     166             :   0, 0, 0, 0, 1, 0,
     167             :   0, 0, 0, 1, 0, 0,
     168             :   0, 0, 1, 0, 0, 0,
     169             :   0, 1, 0, 0, 0, 0,
     170             :   1, 0, 0, 0, 0, 0
     171             : */
     172             : static unsigned char DIGIT_7 [] =
     173             :   { ON_5 | ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
     174             :     ON_0,
     175             :     ON_1,
     176             :     ON_2,
     177             :     ON_3,
     178             :     ON_4,
     179             :     ON_5
     180             :   };
     181             : 
     182             : /*
     183             :   0, 1, 1, 1, 1, 1,
     184             :   1, 0, 0, 0, 0, 1,
     185             :   1, 0, 0, 0, 0, 1,
     186             :   0, 1, 1, 1, 1, 0,
     187             :   1, 0, 0, 0, 0, 1,
     188             :   1, 0, 0, 0, 0, 1,
     189             :   0, 1, 1, 1, 1, 0
     190             : */
     191             : static unsigned char DIGIT_8 [] =
     192             :   { ON_4 | ON_3 | ON_2 | ON_1,
     193             :     ON_5 | ON_0,
     194             :     ON_5 | ON_0,
     195             :     ON_4 | ON_3 | ON_2 | ON_1,
     196             :     ON_5 | ON_0,
     197             :     ON_5 | ON_0,
     198             :     ON_4 | ON_3 | ON_2 | ON_1,
     199             :   };
     200             : 
     201             : /*
     202             :   0, 1, 1, 1, 1, 1,
     203             :   1, 0, 0, 0, 0, 1,
     204             :   1, 0, 0, 0, 0, 1,
     205             :   0, 1, 1, 1, 1, 1,
     206             :   0, 0, 0, 0, 0, 1,
     207             :   0, 0, 0, 0, 0, 1,
     208             :   0, 1, 1, 1, 1, 0
     209             : */
     210             : static unsigned char DIGIT_9 [] =
     211             :   { ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
     212             :     ON_5 | ON_0,
     213             :     ON_5 | ON_0,
     214             :     ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
     215             :     ON_0,
     216             :     ON_0,
     217             :     ON_4 | ON_3 | ON_2 | ON_1,
     218             :   };
     219             : 
     220             : static unsigned char *DIGITS[] = {
     221             :     DIGIT_0,
     222             :     DIGIT_1,
     223             :     DIGIT_2,
     224             :     DIGIT_3,
     225             :     DIGIT_4,
     226             :     DIGIT_5,
     227             :     DIGIT_6,
     228             :     DIGIT_7,
     229             :     DIGIT_8,
     230             :     DIGIT_9
     231             : };
     232             : 
     233           0 :   YuvStamper::YuvStamper(unsigned char* pYData,
     234             :                          uint32_t width,
     235             :                          uint32_t height,
     236             :                          uint32_t stride,
     237             :                          uint32_t x,
     238             :                          uint32_t y,
     239             :                          unsigned char symbol_width,
     240           0 :                          unsigned char symbol_height):
     241             :     pYData(pYData), mStride(stride),
     242             :     mWidth(width), mHeight(height),
     243             :     mSymbolWidth(symbol_width), mSymbolHeight(symbol_height),
     244           0 :     mCursor(x, y) {}
     245             : 
     246           0 :   bool YuvStamper::Encode(uint32_t width, uint32_t height, uint32_t stride,
     247             :                           unsigned char* pYData, unsigned char* pMsg, size_t msg_len,
     248             :                           uint32_t x, uint32_t y)
     249             :   {
     250             :     YuvStamper stamper(pYData, width, height, stride,
     251           0 :                        x, y, sBitSize, sBitSize);
     252             : 
     253             :     // Reserve space for a checksum.
     254           0 :     if (stamper.Capacity() < 8 * (msg_len + sizeof(uint32_t)))
     255             :     {
     256           0 :       return false;
     257             :     }
     258             : 
     259           0 :     bool ok = false;
     260             :     uint32_t crc;
     261           0 :     unsigned char* pCrc = reinterpret_cast<unsigned char*>(&crc);
     262           0 :     r_crc32(reinterpret_cast<char*>(pMsg), (int)msg_len, &crc);
     263           0 :     crc = htonl(crc);
     264             : 
     265           0 :     while (msg_len-- > 0) {
     266           0 :       if (!stamper.Write8(*pMsg++)) {
     267           0 :         return false;
     268             :       }
     269             :     }
     270             : 
     271             :     // Add checksum after the message.
     272           0 :     ok = stamper.Write8(*pCrc++) &&
     273           0 :          stamper.Write8(*pCrc++) &&
     274           0 :          stamper.Write8(*pCrc++) &&
     275           0 :          stamper.Write8(*pCrc++);
     276             : 
     277           0 :     return ok;
     278             :   }
     279             : 
     280           0 :   bool YuvStamper::Decode(uint32_t width, uint32_t height, uint32_t stride,
     281             :                           unsigned char* pYData, unsigned char* pMsg, size_t msg_len,
     282             :                           uint32_t x, uint32_t y)
     283             :   {
     284             :     YuvStamper stamper(pYData, width, height, stride,
     285           0 :                        x, y, sBitSize, sBitSize);
     286             : 
     287           0 :     unsigned char* ptr = pMsg;
     288           0 :     size_t len = msg_len;
     289             :     uint32_t crc, msg_crc;
     290           0 :     unsigned char* pCrc = reinterpret_cast<unsigned char*>(&crc);
     291             : 
     292             :     // Account for space reserved for the checksum
     293           0 :     if (stamper.Capacity() < 8 * (len + sizeof(uint32_t))) {
     294           0 :       return false;
     295             :     }
     296             : 
     297           0 :     while (len-- > 0) {
     298           0 :       if(!stamper.Read8(*ptr++)) {
     299           0 :         return false;
     300             :       }
     301             :     }
     302             : 
     303           0 :     if (!(stamper.Read8(*pCrc++) &&
     304           0 :           stamper.Read8(*pCrc++) &&
     305           0 :           stamper.Read8(*pCrc++) &&
     306           0 :           stamper.Read8(*pCrc++))) {
     307           0 :       return false;
     308             :     }
     309             : 
     310           0 :     r_crc32(reinterpret_cast<char*>(pMsg), (int)msg_len, &msg_crc);
     311           0 :     return crc == htonl(msg_crc);
     312             :   }
     313             : 
     314           0 :   inline uint32_t YuvStamper::Capacity()
     315             :   {
     316             :     // Enforce at least a symbol width and height offset from outer edges.
     317           0 :     if (mCursor.y + mSymbolHeight > mHeight) {
     318           0 :       return 0;
     319             :     }
     320             : 
     321           0 :     if (mCursor.x + mSymbolWidth > mWidth && !AdvanceCursor()) {
     322           0 :       return 0;
     323             :     }
     324             : 
     325             :     // Normalize frame integral to mSymbolWidth x mSymbolHeight
     326           0 :     uint32_t width = mWidth / mSymbolWidth;
     327           0 :     uint32_t height = mHeight / mSymbolHeight;
     328           0 :     uint32_t x = mCursor.x / mSymbolWidth;
     329           0 :     uint32_t y = mCursor.y / mSymbolHeight;
     330             : 
     331           0 :     return (width * height - width * y)- x;
     332             :   }
     333             : 
     334           0 :   bool YuvStamper::Write8(unsigned char value)
     335             :   {
     336             :     // Encode MSB to LSB.
     337           0 :     unsigned char mask = 0x80;
     338           0 :     while (mask) {
     339           0 :       if (!WriteBit(!!(value & mask))) {
     340           0 :         return false;
     341             :       }
     342           0 :       mask >>= 1;
     343             :     }
     344           0 :     return true;
     345             :   }
     346             : 
     347           0 :   bool YuvStamper::WriteBit(bool one)
     348             :   {
     349             :     // A bit is mapped to a mSymbolWidth x mSymbolHeight square of luma data points.
     350             :     // Don't use ternary op.: https://bugzilla.mozilla.org/show_bug.cgi?id=1001708
     351             :     unsigned char value;
     352           0 :     if (one)
     353           0 :       value = sYOn;
     354             :     else
     355           0 :       value = sYOff;
     356             : 
     357           0 :     for (uint32_t y = 0; y < mSymbolHeight; y++) {
     358           0 :       for (uint32_t x = 0; x < mSymbolWidth; x++) {
     359           0 :         *(pYData + (mCursor.x + x) + ((mCursor.y + y) * mStride)) = value;
     360             :       }
     361             :     }
     362             : 
     363           0 :     return AdvanceCursor();
     364             :   }
     365             : 
     366           0 :   bool YuvStamper::AdvanceCursor()
     367             :   {
     368           0 :     mCursor.x += mSymbolWidth;
     369           0 :     if (mCursor.x + mSymbolWidth > mWidth) {
     370             :       // move to the start of the next row if possible.
     371           0 :       mCursor.y += mSymbolHeight;
     372           0 :       if (mCursor.y + mSymbolHeight > mHeight) {
     373             :         // end of frame, do not advance
     374           0 :         mCursor.y -= mSymbolHeight;
     375           0 :         mCursor.x -= mSymbolWidth;
     376           0 :         return false;
     377             :       } else {
     378           0 :         mCursor.x = 0;
     379             :       }
     380             :     }
     381             : 
     382           0 :     return true;
     383             :   }
     384             : 
     385           0 :   bool YuvStamper::Read8(unsigned char &value)
     386             :   {
     387           0 :     unsigned char octet = 0;
     388           0 :     unsigned char bit = 0;
     389             : 
     390           0 :     for (int i = 8; i > 0; --i) {
     391           0 :       if (!ReadBit(bit)) {
     392           0 :         return false;
     393             :       }
     394           0 :       octet <<= 1;
     395           0 :       octet |= bit;
     396             :     }
     397             : 
     398           0 :     value = octet;
     399           0 :     return true;
     400             :   }
     401             : 
     402           0 :   bool YuvStamper::ReadBit(unsigned char &bit)
     403             :   {
     404           0 :     uint32_t sum = 0;
     405           0 :     for (uint32_t y = 0; y < mSymbolHeight; y++) {
     406           0 :       for (uint32_t x = 0; x < mSymbolWidth; x++) {
     407           0 :         sum += *(pYData + mStride * (mCursor.y + y) + mCursor.x + x);
     408             :       }
     409             :     }
     410             : 
     411             :     // apply threshold to collected bit square
     412           0 :     bit = (sum > (sBitThreshold * mSymbolWidth * mSymbolHeight)) ? 1 : 0;
     413           0 :     return AdvanceCursor();
     414             :   }
     415             : 
     416           0 :   bool YuvStamper::WriteDigits(uint32_t value)
     417             :   {
     418             :     char buf[20];
     419           0 :     SprintfLiteral(buf, "%.5u", value);
     420           0 :     size_t size = strlen(buf);
     421             : 
     422           0 :     if (Capacity() < size) {
     423           0 :       return false;
     424             :     }
     425             : 
     426           0 :     for (size_t i=0; i < size; ++i) {
     427           0 :       if (!WriteDigit(buf[i] - '0'))
     428           0 :         return false;
     429           0 :       if (!AdvanceCursor()) {
     430           0 :         return false;
     431             :       }
     432             :     }
     433             : 
     434           0 :     return true;
     435             :   }
     436             : 
     437           0 :   bool YuvStamper::WriteDigit(unsigned char digit) {
     438           0 :     if (digit > sizeof(DIGITS)/sizeof(DIGITS[0]))
     439           0 :       return false;
     440             : 
     441           0 :     unsigned char *dig = DIGITS[digit];
     442           0 :     for (uint32_t row = 0; row < sDigitHeight; ++row) {
     443           0 :       unsigned char mask = 0x01 << (sDigitWidth - 1);
     444           0 :       for (uint32_t col = 0; col < sDigitWidth; ++col, mask >>= 1) {
     445           0 :         if (dig[row] & mask) {
     446           0 :           for (uint32_t xx=0; xx < sPixelSize; ++xx) {
     447           0 :             for (uint32_t yy=0; yy < sPixelSize; ++yy) {
     448           0 :               WritePixel(pYData,
     449           0 :                          mCursor.x + (col * sPixelSize) + xx,
     450           0 :                          mCursor.y + (row * sPixelSize) + yy);
     451             :             }
     452             :           }
     453             :         }
     454             :       }
     455             :     }
     456             : 
     457           0 :     return true;
     458             :   }
     459             : 
     460           0 :   void YuvStamper::WritePixel(unsigned char *data, uint32_t x, uint32_t y) {
     461           0 :     unsigned char *ptr = &data[y * mStride + x];
     462             :     // Don't use ternary op.: https://bugzilla.mozilla.org/show_bug.cgi?id=1001708
     463           0 :     if (*ptr > sLumaThreshold)
     464           0 :       *ptr = sLumaMin;
     465             :     else
     466           0 :       *ptr = sLumaMax;
     467           0 :    }
     468             : 
     469             : } // namespace mozilla.

Generated by: LCOV version 1.13