title: Decoding YUV to RGB in C/C++ with NDK
body: <p>I'm trying to convert the Android camera feed to a bitmap for image processing.</p>
  
  <p>I have some code that converts YUV to RGB in native java which works, however, this process isn't quick enough for real time video so I think I need to convert it in either C or C++ before I apply the filters. I already have the NDK set up and working so the only bit I don't know how to do is port the following code to C or C++:</p>
  
  <pre><code>// decode Y, U, and V values on the YUV 420 buffer described as YCbCr_422_SP by Android 
  // David Manpearl 081201 
  public void decodeYUV(int[] out, byte[] fg, int width, int height)
          throws NullPointerException, IllegalArgumentException {
      int sz = width * height;
      if (out == null)
          throw new NullPointerException("buffer out is null");
      if (out.length &lt; sz)
          throw new IllegalArgumentException("buffer out size " + out.length
                  + " &lt; minimum " + sz);
      if (fg == null)
          throw new NullPointerException("buffer 'fg' is null");
      if (fg.length &lt; sz)
          throw new IllegalArgumentException("buffer fg size " + fg.length
                  + " &lt; minimum " + sz * 3 / 2);
      int i, j;
      int Y, Cr = 0, Cb = 0;
      for (j = 0; j &lt; height; j++) {
          int pixPtr = j * width;
          final int jDiv2 = j &gt;&gt; 1;
          for (i = 0; i &lt; width; i++) {
              Y = fg[pixPtr];
              if (Y &lt; 0)
                  Y += 255;
              if ((i &amp; 0x1) != 1) {
                  final int cOff = sz + jDiv2 * width + (i &gt;&gt; 1) * 2;
                  Cb = fg[cOff];
                  if (Cb &lt; 0)
                      Cb += 127;
                  else
                      Cb -= 128;
                  Cr = fg[cOff + 1];
                  if (Cr &lt; 0)
                      Cr += 127;
                  else
                      Cr -= 128;
              }
              int R = Y + Cr + (Cr &gt;&gt; 2) + (Cr &gt;&gt; 3) + (Cr &gt;&gt; 5);
              if (R &lt; 0)
                  R = 0;
              else if (R &gt; 255)
                  R = 255;
              int G = Y - (Cb &gt;&gt; 2) + (Cb &gt;&gt; 4) + (Cb &gt;&gt; 5) - (Cr &gt;&gt; 1)
                      + (Cr &gt;&gt; 3) + (Cr &gt;&gt; 4) + (Cr &gt;&gt; 5);
              if (G &lt; 0)
                  G = 0;
              else if (G &gt; 255)
                  G = 255;
              int B = Y + Cb + (Cb &gt;&gt; 1) + (Cb &gt;&gt; 2) + (Cb &gt;&gt; 6);
              if (B &lt; 0)
                  B = 0;
              else if (B &gt; 255)
                  B = 255;
              out[pixPtr++] = 0xff000000 + (B &lt;&lt; 16) + (G &lt;&lt; 8) + R;
          }
      }
  
  }
  </code></pre>
  
  <p>...</p>
  
  <pre><code>decodeYUV(argb8888, data, camSize.width, camSize.height);
  Bitmap bitmap = Bitmap.createBitmap(argb8888, camSize.width,
                      camSize.height, Config.ARGB_8888);
  </code></pre>
  
  <p>Does anyone know how to do this?</p>
  
  <p>Many thanks!</p>
  
  <hr>
  
  <p>Update</p>
  
  <p>This is how far I've got:</p>
  
  <pre><code>JNIEXPORT void JNICALL Java_com_twothreetwo_zoomplus_ZoomPlus_YUVtoRGB(JNIEnv * env, jobject obj, jintArray rgb, jbyteArray yuv420sp, jint width, jint height)
  {
      int             sz;
      int             i;
      int             j;
      int             Y;
      int             Cr = 0;
      int             Cb = 0;
      int             pixPtr = 0;
      int             jDiv2 = 0;
      int             R = 0;
      int             G = 0;
      int             B = 0;
      int             cOff;
  
      sz = width * height;
       //if(out == null) throw new NullPointerException("buffer 'out' is null");
       //if(out.length &lt; sz) throw new IllegalArgumentException("buffer 'out' size " + out.length + " &lt; minimum " + sz);
       //if(fg == null) throw new NullPointerException("buffer 'fg' is null");
       //if(fg.length &lt; sz) throw new IllegalArgumentException("buffer 'fg' size " + fg.length + " &lt; minimum " + sz * 3/ 2);
       for(j = 0; j &lt; height; j++) {
               pixPtr = j * width;
               jDiv2 = j &gt;&gt; 1;
               for(i = 0; i &lt; width; i++) {
                       Y = yuv420sp[pixPtr]; if(Y &lt; 0) Y += 255;
                       if((i &amp; 0x1) != 1) {
                               cOff = sz + jDiv2 * width + (i &gt;&gt; 1) * 2;
                               Cb = yuv420sp[cOff];
                               if(Cb &lt; 0) Cb += 127; else Cb -= 128;
                               Cr = yuv420sp[cOff + 1];
                               if(Cr &lt; 0) Cr += 127; else Cr -= 128;
                       }
                       R = Y + Cr + (Cr &gt;&gt; 2) + (Cr &gt;&gt; 3) + (Cr &gt;&gt; 5);
                       if(R &lt; 0) R = 0; else if(R &gt; 255) R = 255;
                       G = Y - (Cb &gt;&gt; 2) + (Cb &gt;&gt; 4) + (Cb &gt;&gt; 5) - (Cr &gt;&gt; 1) + (Cr &gt;&gt; 3) + (Cr &gt;&gt; 4) + (Cr &gt;&gt; 5);
                       if(G &lt; 0) G = 0; else if(G &gt; 255) G = 255;
                       B = Y + Cb + (Cb &gt;&gt; 1) + (Cb &gt;&gt; 2) + (Cb &gt;&gt; 6);
                       if(B &lt; 0) B = 0; else if(B &gt; 255) B = 255;
                       rgb[pixPtr++] = 0xff000000 + (B &lt;&lt; 16) + (G &lt;&lt; 8) + R;
               }
       }
  
  }
  </code></pre>
  
  <p>But I'm getting the following C errors:</p>
  
  <pre><code>apps/zoomplusndk/jni/zoomplusndk.c:53: warning: dereferencing 'void *' pointer
  apps/zoomplusndk/jni/zoomplusndk.c:53: error: void value not ignored as it ought to be
  apps/zoomplusndk/jni/zoomplusndk.c:56: warning: dereferencing 'void *' pointer
  apps/zoomplusndk/jni/zoomplusndk.c:56: error: void value not ignored as it ought to be
  apps/zoomplusndk/jni/zoomplusndk.c:58: warning: dereferencing 'void *' pointer
  apps/zoomplusndk/jni/zoomplusndk.c:58: error: void value not ignored as it ought to be
  apps/zoomplusndk/jni/zoomplusndk.c:67: warning: dereferencing 'void *' pointer
  apps/zoomplusndk/jni/zoomplusndk.c:67: error: invalid use of void expression
  </code></pre>
  
  <p>Line 53 is Y = yuv420sp[pixPtr]; if(Y &lt; 0) Y += 255;</p>