How can I get first 10-bits of UInt16 type? - c#-4.0

I want to take first 10-bits value of UInt16 value. I tried;
x = (x & 0x00001111111111 )
But it gives me an error : Cannot convert type 'int' to 'ushort'.

How about, as 0x3FF in binary is 0000 0011 1111 1111
x = (UInt16)(x & 0x3FF)

You may try like this:-
UInt16 val1 = 8;
UInt16 value = (UInt16)(val1 << 6);
or simply cast it like this:-
x = (UInt16)(x & 0x3FF)

Related

V4L2_PIX_FMT_YUYV: convert from YUYV to RGB24?

I'm capturing image data from a webcam using Video4Linux2. The pixel format returned by the device is V4L2_PIX_FMT_YUYV. According to http://linuxtv.org/downloads/v4l-dvb-apis/V4L2-PIX-FMT-YUYV.html this is the same as YUV422 so I used a YUV422 to RGB24 conversion based on the description at http://paulbourke.net/dataformats/yuv/ .
Amazingly the result is a strange violet/green picture. So it seems YUYV is something different than YUV422 (and there also exists a pixel format V4L2_PIX_FMT_YUV422P which is/is not the same?).
So I'm totally confused now: how can I convert a V4L2_PIX_FMT_YUYV bitmap to real RGB24? Are there any examples out there?
Too long to put in a comment...
4:2:2 is not a pixel-format, it is just a notation about how the chroma-data have been subsampled. According to the linuxtv-link, V4L2_PIX_FMT_YUYV is identical to YUYV or YUY2.
The ultimate reference on the subject is http://www.fourcc.org. Have a look at what it says about YUY2 at http://www.fourcc.org/yuv.php#YUYV
Horizontal Vertical
Y Sample Period 1 1
V Sample Period 2 1
U Sample Period 2 1
To verify that that the input format indeed is YUYV you can use a viewer I wrote using SDL; which natively supports this format (among others)
https://github.com/figgis/yuv-viewer
See also http://www.fourcc.org/fccyvrgb.php for correct formulas for rgb/yuv-conversion.
Take it from there and drop me a comment if you need further assistance...
I had a similar problem and the issue was endianness. V4L returns pixel data as a series of bytes which I was casting to 16 bit ints. Because of the endianness of my machine the Y and Cb (or Y and Cr for odd pixels) values were getting swapped and I was getting a weird violet/green image.
The solution was just to change how I was extracting Y, Cb and Cr from my 16 bit ints. That is to say, instead of this:
int y = pixbuf[i] & 0xFF00) >> 8;
int u = pixbuf[(i / 2) * 2] & 0xFF;
int v = pixbuf[(i / 2) * 2 + 1] & 0xFF;
I should have done this:
int y = (pixbuf[i] & 0xFF);
int u = (pixbuf[(i / 2) * 2] & 0xFF00) >> 8;
int v = (pixbuf[(i / 2) * 2 + 1] & 0xFF00) >> 8;
Or indeed just processed them as a sequence of bytes like a sensible person...

How to sum up elements of an arraylist having type String?

I have an arraylist consisting of decimal numbers and i m supposed to take the average of last 4 elements of this arraylist.And these rational number are type of String.
private void average(String confidence) {
if(myList.size() >= 4) {
String t = myList.get(myList.size()-1);
String d = myList.get(myList.size()-2);
String f = myList.get(myList.size()-3);
String h = myList.get(myList.size()-4);
String s = (t + d + f+h) ;
long fin = Long.parseLong(s);
long result = fin/4 ;
System.out.println("Average is: "+result);
}
but this method does not work.Could you please tell me what kind of changes am i supposed to do or any advices of doing this? Thanks a lot in advance!!!
Your issue is the String s = (t + d + f+h) part. You're just appending 4 Strings right now.
You need to convert them first.
And your result will be wrong, you need to divide by 4, not 3.
Colleen's answer is good, so long as you remember to change the type to reflect what Long.parseLong() returns. I'd reply, but I'm too new.
if(myList.size() >= 4) {
Double t = Double.parseLong(myList.get(conf.size()-1));
Double d = Double.pareseLong(myList.get(conf.size()-2));
Double f = Double.parseLong(myList.get(conf.size()-3));
Double h = Double.parseLong(myList.get(conf.size()-4));
Double result = (t + d + f + h) / 3 ;
System.out.println("meanAsrConfidence is: "+result);
}
You need to convert before you add. + on Strings means concatenate.
if(myList.size() >= 4) {
//I'm guessing all of these conf.size() calls are meant to be myList.size()
double t = Double.parseDouble(myList.get(conf.size()-1));
double d = Double.pareseDouble(myList.get(conf.size()-2));
double f = Double.parseDouble(myList.get(conf.size()-3));
double h = Double.parseDoublemyList.get(conf.size()-4));
double s = (t + d + f+h) ;
double result = s/3 ; //should be 4
System.out.println("meanAsrConfidence is: "+result);
}
What you are doing now is, for example:
t=1, d=2, f=3, h=4
s = 1234
Also:
you need to divide by 4, not 3
what is conf? Why are you not calling myList.size()?
you're passing a String as an argument when you probably want to be passing myList

Audio data (unsigned char) that have been manipulated cannot be played

I have trouble with playing audio data after they have been manipulated.
The only API I use is the alsa lib API on Linux (Ubuntu) in C.
I get the data from a 16 bits integer wave file in a unsigned char array (called buffer1) using read() and buffer1 can be played properly. I want the data to be passed to another unsigned char array (called buffer2) of the same size. If I just make a loop with buffer2[i] = buffer1[i], it works : buffer2 can be played properly. But in order to manipulate the data, I convert it to a float array then back to unsigned char (Until now I do not manipulate the audio data; I just convert them to float then back to unsigned char to test how it works). But now buffer2 does not make sound although all of its values are strictly identical to the values of buffer1 (I made a printf of many values of buffer1 and buffer2; they are all identical) ... All I did is casting from unsigned to float and vice versa...
Please any idea of what's wrong?
Victor
The values in buffer1 and buffer2 cannot be identical or it would work. Perhaps the formatting that you use in your printf command is masking the differences (%i, %f etc.). Rather than use printf, try setting a breakpoint and looking at the values using your debugger. This might help reveal what is actually going wrong.
EDIT:
Given your comments about how you perform the cast, I think that I can now help. The raw data coming in is of type unsigned char. On most platforms, this will be an integer value between 0 and 255. You want to convert this value to a float to do your manipulation. To make the data meaningful as a floating point type for any manipulation, you want to scale this range between +/- 1.0. This is what the "scale" variable is for in the following code.
#include <iostream>
#include <math.h>
int main()
{
const int BUFFER_LEN = 6;
const unsigned char channelDataIN[] = {0,255, 1, 254, 2, 253};
unsigned char channelDataOUT[BUFFER_LEN];
float channelDataF[BUFFER_LEN];
std::cout.precision(5);
float scale = powf(2.f, 8.f*sizeof(unsigned char) ) - 1.f;
for (int mm = 0; mm < BUFFER_LEN; ++mm)
{
std::cout << "Original = " << (int)channelDataIN[mm] << std::endl;
channelDataF[mm] = (float)(channelDataIN[mm]) * 2.f/scale - 1.f; //Float cast
std::cout << "Float conversion = " << channelDataF[mm] << std::endl;
channelDataOUT[mm] = (unsigned char) ceil( ( 1.f+channelDataF[mm] ) * scale/2.f );
std::cout << "Recovered = " << (int)channelDataOUT[mm] << std::endl;
if (channelDataIN[mm] == channelDataOUT[mm])
std::cout << "The output precisely equals the input" << std::endl << std::endl;
else
std::cout << "The output != input" << std::endl << std::endl;
}
return 0;
}
The output array of unsigned chars after converting the values back is identical to the input array. This is the output from the code . . .
Original = 0
Float conversion = -1
Recovered = 0
The output precisely equals the input
Original = 255
Float conversion = 1
Recovered = 255
The output precisely equals the input
Original = 1
Float conversion = -0.99216
Recovered = 1
The output precisely equals the input
Original = 254
Float conversion = 0.99216
Recovered = 254
The output precisely equals the input
Original = 2
Float conversion = -0.98431
Recovered = 2
The output precisely equals the input
Original = 253
Float conversion = 0.98431
Recovered = 253
The output precisely equals the input

How would you average two 32-bit colors packed into an integer?

I'm trying to average two colors.
My original (horrible) implement is as follows:
//color is a union
int ColorAverage(int c1, int c2) {
color C1(c1);
color C2(c2);
return color(
(unsigned char)(0.5f * C1.a + 0.5f * C2.a),
(unsigned char)(0.5f * C1.r + 0.5f * C2.r),
(unsigned char)(0.5f * C1.g + 0.5f * C2.g),
(unsigned char)(0.5f * C1.b + 0.5f * C2.b)
).c;
}
My current solution is as follows (which performs considerably better):
int ColorAverage(int c1, int c2) {
unsigned char* b1 = reinterpret_cast<unsigned char*>(&c1);
unsigned char* b2 = reinterpret_cast<unsigned char*>(&c2);
int value;
unsigned char* bv = reinterpret_cast<unsigned char*>(&value);
bv[0] = (b1[0] + b2[0]) / 2;
bv[1] = (b1[1] + b2[1]) / 2;
bv[2] = (b1[2] + b2[2]) / 2;
bv[3] = (b1[3] + b2[3]) / 2;
return(value);
}
However, it's still quite slow (it's about 3% of my frame time).
I did find a solution for 24bit, but it does not apply to 32bit (the alpha is lost):
#define AVERAGE(a, b) ( ((((a) ^ (b)) & 0xfffefefeL) >> 1) + ((a) & (b)) )
http://www.compuphase.com/graphic/scale3.htm#HSIEH1
Try extending your mask to 32 bits, like this:
#define AVERAGE(a, b) ( ((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b)) )
Edit: I did a quick check, and it appears to work for my test case. Nice formula, by the way!
The goal is to take the following operation:
(a + b) / 2 = ((a ^ b) >> 1) + (a & b)
And apply it to all four bytes of the integer. If this were just one byte, then the right shift by 1 bit would discard the right-most bit. However, in this case, the right-most bit of the leading 3 bytes isn't discarded---it's shifted into the neighboring byte. The idea to keep in mind is that you need the mask the last bit of each byte so that it doesn't 'contaminate' the neighboring byte during the shift. For example, say that a ^ b is this:
a XOR b = 1011 1101 1110 1001
A right-shift of 1 bit, without the mask, would look like this:
(a XOR b) >> 1 = 0101 1110 1111 0100
Which is wrong. The mask zero's out the last bit of each byte, so that this doesn't happen:
(a XOR b) AND 0xfefefefe = 1010 1100 1110 1000
Then you can shift this value safely to the right:
((a XOR b) AND 0xfefefefe) = 0101 0110 0111 0100
So:
#define AVERAGE(a, b) ( ((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b)) )
One thing to keep in mind is that C does not differentiate arithmetic right shift from logical right shift with its operator. You'll want to make sure that the integers you are shifting are unsigned, to prevent implementation-specific signed-integer shift voodoo.
EDIT: I think #dasblinkenlight may have beaten me the this answer. Just beware of shifting signed integers and you should be good.

What's the most effective way to interpolate between two colors? (pseudocode and bitwise ops expected)

Making a Blackberry app, want a Gradient class. What's the most effective way (as in, speed and battery life) to interpolate two colors? Please be specific.
// Java, of course
int c1 = 0xFFAA0055 // color 1, ARGB
int c2 = 0xFF00CCFF // color 2, ARGB
float st = 0 // the current step in the interpolation, between 0 and 1
Help from here on.
Should I separate each channel of each color, convert them to decimal and interpolate? Is there a simpler way?
interpolatedChannel = red1+((red2-red1)*st)
interpolatedChannel = interpolatedChannel.toString(16)
^ Is this the right thing to do? If speed and effectiveness
is important in a mobile app, should I use bitwise operations?
Help me!
You'll have to separate channels, but there's no need to convert them to decimal.
For example, if you allow 256 possible gradients:
red = red1 + ((red2 - red1) * stage / 256)
EDIT: Since you said you don't know much about bit management, here's a quick way to split channels:
red = color & 0x000000ff;
green = color & 0x0000ff00;
blue = color & 0x00ff0000;
alpha = color >> 24;
And combining them back:
color = (alpha << 24) | blue | green | red;
From here, the details should normally be handled by the compiler optimizations. If anything, you're looking for the best algorithm.
private function interpolateColorsCompact( a:int, b:int, lerp:Number ):int
{
var MASK1:int = 0xff00ff;
var MASK2:int = 0x00ff00;
var f2:int = 256 * lerp;
var f1:int = 256 - f2;
return ((((( a & MASK1 ) * f1 ) + ( ( b & MASK1 ) * f2 )) >> 8 ) & MASK1 )
| ((((( a & MASK2 ) * f1 ) + ( ( b & MASK2 ) * f2 )) >> 8 ) & MASK2 );
}
Not sure if this is the most compact way of doing it, but it uses less local variables and less operators than the classic method that splis them into 3 channels first.
Oh - and sorry that this is Actionscript, but it should be clear how to convert this to Java.
Updated my answer (found a better way):
The following technique will lose 1 bit precision per channel, but it's extremely fast, since you won't have to split the colors into channels:
int color1 = ...;
int color2 = ...;
int interpolatedColor = ((color1 & 0xFEFEFEFE) >> 1) +
((color2 & 0xFEFEFEFE) >> 1));
So, first you AND both colors by 0xFEFEFEFE. This removes the last bit per channel (reduces precision, as I said). After that, you can safely divide the entire value by 2 (implemented as a right-shift by 1). Finally, you just add up the two values.
Just the java version of /u/Quasimondo's answer:
public static int mixColors(int a, int b, float ratio){
int mask1 = 0x00ff00ff;
int mask2 = 0xff00ff00;
int f2 = (int)(256 * ratio);
int f1 = 256 - f2;
return (((((a & mask1) * f1) + ((b & mask1) * f2)) >> 8) & mask1)
| (((((a & mask2) * f1) + ((b & mask2) * f2)) >> 8) & mask2);
}
If you only need exact 50/50 ratios you can cut out the bitshifting:
public static int mixColors(int a, int b){
int mask1 = 0x00ff00ff;
int mask2 = 0xff00ff00;
return (((a & mask1) + (b & mask1)) & mask1)
| (((a & mask2) + (b & mask2)) & mask2);
}

Resources