public int hleJpegDecodeYCbCr(BufferedImage bufferedImage,TPointer yCbCrBuffer,int yCbCrBufferSize,int dhtMode){
  int width=bufferedImage.getWidth();
  int height=bufferedImage.getHeight();
  int sizeY=width * height;
  int sizeCb=sizeY >> 2;
  int addressY=yCbCrBuffer.getAddress();
  int addressCb=addressY + sizeY;
  int addressCr=addressCb + sizeCb;
  if (log.isDebugEnabled()) {
    log.debug(String.format("hleJpegDecodeYCbCr 0x%08X, 0x%08X, 0x%08X",addressY,addressCb,addressCr));
  }
  int[] bufferCb=new int[sizeCb];
  int[] bufferCr=new int[sizeCb];
  IMemoryWriter imageWriterY=MemoryWriter.getMemoryWriter(addressY,sizeY,1);
  for (int y=0; y < height; y++) {
    int indexCb=(y >> 1) * (width >> 1);
    for (int x=0; x < width; x+=2, indexCb++) {
      int argb0=bufferedImage.getRGB(x,y);
      int yCbCr0=colorARGBToYCbCr(argb0);
      int argb1=bufferedImage.getRGB(x + 1,y);
      int yCbCr1=colorARGBToYCbCr(argb1);
      imageWriterY.writeNext(getY(yCbCr0));
      imageWriterY.writeNext(getY(yCbCr1));
      bufferCb[indexCb]+=getCb(yCbCr0);
      bufferCb[indexCb]+=getCb(yCbCr1);
      bufferCr[indexCb]+=getCr(yCbCr0);
      bufferCr[indexCb]+=getCr(yCbCr1);
    }
  }
  imageWriterY.flush();
  IMemoryWriter imageWriterCb=MemoryWriter.getMemoryWriter(addressCb,sizeCb,1);
  IMemoryWriter imageWriterCr=MemoryWriter.getMemoryWriter(addressCr,sizeCb,1);
  for (int i=0; i < sizeCb; i++) {
    imageWriterCb.writeNext(bufferCb[i] >> 2);
    imageWriterCr.writeNext(bufferCr[i] >> 2);
  }
  imageWriterCb.flush();
  imageWriterCr.flush();
  return getWidthHeight(width,height);
}

public int hleJpegDecodeYCbCr ( BufferedImage bufferedImage , TPointer yCbCrBuffer , int yCbCrBufferSize , int dhtMode ) { int width = bufferedImage . getWidth ( ) ; int height = bufferedImage . getHeight ( ) ; int sizeY = width * height ; int sizeCb = sizeY > > 2 ; int addressY = yCbCrBuffer . getAddress ( ) ; int addressCb = addressY + sizeY ; int addressCr = addressCb + sizeCb ; if ( log . isDebugEnabled ( ) ) { log . debug ( String . format ( "hleJpegDecodeYCbCr 0x%08X, 0x%08X, 0x%08X" , addressY , addressCb , addressCr ) ) ; } int [ ] bufferCb = new int [ sizeCb ] ; int [ ] bufferCr = new int [ sizeCb ] ; IMemoryWriter imageWriterY = MemoryWriter . getMemoryWriter ( addressY , sizeY , 1 ) ; for ( int y = 0 ; y < height ; y ++ ) { int indexCb = ( y > > 1 ) * ( width > > 1 ) ; for ( int x = 0 ; x < width ; x += 2 , indexCb ++ ) { int argb0 = bufferedImage . getRGB ( x , y ) ; int yCbCr0 = colorARGBToYCbCr ( argb0 ) ; int argb1 = bufferedImage . getRGB ( x + 1 , y ) ; int yCbCr1 = colorARGBToYCbCr ( argb1 ) ; imageWriterY . writeNext ( getY ( yCbCr0 ) ) ; imageWriterY . writeNext ( getY ( yCbCr1 ) ) ; bufferCb [ indexCb ] += getCb ( yCbCr0 ) ; bufferCb [ indexCb ] += getCb ( yCbCr1 ) ; bufferCr [ indexCb ] += getCr ( yCbCr0 ) ; bufferCr [ indexCb ] += getCr ( yCbCr1 ) ; } } imageWriterY . flush ( ) ; IMemoryWriter imageWriterCb = MemoryWriter . getMemoryWriter ( addressCb , sizeCb , 1 ) ; IMemoryWriter imageWriterCr = MemoryWriter . getMemoryWriter ( addressCr , sizeCb , 1 ) ; for ( int i = 0 ; i < sizeCb ; i ++ ) { imageWriterCb . writeNext ( bufferCb [ i ] > > 2 ) ; imageWriterCr . writeNext ( bufferCr [ i ] > > 2 ) ; } imageWriterCb . flush ( ) ; imageWriterCr . flush ( ) ; return getWidthHeight ( width , height ) ; }
convert an image to yuv420p format . see http : / / en . wikipedia . org / wiki / yuv # y . 27uv420p_ . 28and_y . 27v12_or_yv12 . 29_to_rgb888_conversion for the description of the yuv420p format : " y ' uv420p is a planar format , meaning that the y ' , u , and v values are grouped together instead of interspersed . the reason for this is that by grouping the u and v values together , the image becomes much more compressible . when given an array of an image in the y ' uv420p format , all the y ' values come first , followed by all the u values , followed finally by all the v values . as with most y ' uv formats , there are as many y ' values as there are pixels . where x equals the height multiplied by the width , the first x indices in the array are y ' values that correspond to each individual pixel . however , there are only one fourth as many u and v values . the u and v values correspond to each 2 by 2 block of the image , meaning each u and v entry applies to four pixels . after the y ' values , the next x / 4 indices are the u values for each 2 by 2 block , and the next x / 4 indices after that are the v values that also apply to each 2 by 2 block . size . total = size . width * size . height ; y = yuv [ position . y * size . width + position . x ] ; u = yuv [ ( position . y / 2 ) * ( size . width / 2 ) + ( position . x / 2 ) + size . total ] ; v = yuv [ ( position . y / 2 ) * ( size . width / 2 ) + ( position . x / 2 ) + size . total + ( size . total / 4 ) ] ; rgb = y ' uv444torgb888 ( y , u , v ) ; "
