What does x & 0xfffffe mean?

aminakoy

in a custom YUV to RGBA Renderscript, I have found the following line which I could not understand:

int baseUYIndex = numTotalPixels + (y >> 1) * wIn + (x & 0xfffffe);
  • numTotalPixels is width*height. That is ok.
  • y>>1. Why they do this ?
  • x & 0xfffffe. Why they do this ?

The script is from customYUVToRGBAConverter.

The reason I ask is because I have first to understand the conversion. In a next step, I want to rotate the Y,U and V components by 90 degrees. I asked here for help, but nobody could help. So, I decided to make it myself.

greeble31

Looking at the comment in the linked code, you can see that this routine is intended for a specific kind of YUV: One with chroma subsampling.

// YUV 4:2:0 planar image, with 8 bit Y samples, followed by
// interleaved V/U plane with 8bit 2x2 subsampled chroma samples

What this means is that there are fewer "color" (U/V) bytes than there are "luminance" (Y) bytes. Specifically, a square consisting of 4 pixels in the original image will only be covered by one "U" and one "V". (It'll have 4 Y's, though.) The U's and V's are interleaved into a separate "plane", which follows the Y plane. Here is a link that describes the same arrangement in more detail.

Also refer to this picture on Wikimedia (caution: the linked picture is for a slightly different image format, where the U's and V's aren't interleaved).

CODE ANALYSIS

The code in question takes an (x,y) coordinate for the original image, and calculates the array offset for the U/V component. (The array offset for the Y component is easy; it's just x + y * wIn). Each U/V pair corresponds to a 4-pixel square in the original image; that means each U/V pair covers pixels in 2 adjacent rows.

y >> 1

This line effectively divides y by 2, which gives you the proper row number for the U/V plane. Multiply by wIn (which is the width of the picture), and you have the byte offset, into the U/V plane, of the start of the U/V row that corresponds to your pixel.

x & 0xfffffe

This is equivalent to x - (x % 2). In other words, we're making x even. This is to calculate the offset, into the U/V row, of the U/V pair. Since each U/V is a two-byte pair, we always want to end up on the first element of the pair: A "U", in this case.

As you can see from this code,

uchar _u = rsGetElementAt_uchar(inputAllocation, baseUYIndex);
uchar _v = rsGetElementAt_uchar(inputAllocation, baseUYIndex + 1);

the U comes from the byte at the calculated offset; the V, from the next byte.

And there, you have your chrominance.

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事