Dan said:
I'm trying to figure out how to get bit operators to work on a binary
string. This is what I'm trying to do:
list(frame) #where frame is a binary string
y = frame[x] << 8
You don't describe what you want this to do. How about an example, showing
input and desired output?
It gives me a TypeError. Whats the best way to get around that? I think
the struct module may be what I'm looking for, if so could someone give
me an example? Also, is there a better way to be able to access
individual bytes than converting the string to a list?
Yes, use an array (see the module by that name).
On the other hand, depending on what you really want, the answer might
be as simple as taking your string and skipping the first element.
After all, shifting each byte in a long sequence to the left by 8 bits
is pretty much synonymous with that approach:
out = in[1:] + '\x00'
But I suspect that's not really what you meant. Please explain.
-Peter
Sorry, I should have included more information. I'm trying to write a
webcam app to grab and display images off a Philips (pwc) camera in
Linux. What I have so far is based on the mini-tv.py demo in the pyv4l
module. It will work with RGB output such as from a tv tuner card but
the Philips cameras use a different color palette. I found a C function
that converts the YUV420P color palette to RGB, and I'm trying to
convert it to python. The binary string in question is the image data
for one frame of video. To display it, I'm using PIL's
Image.fromstring() and tkinter.
I don't know much C at all and am fairly new to python as well, but I'll
post what I have so far.
Here's the C version:
static void ccvt_420p(int width, int height, const unsigned char *src,
unsigned char *dst, int push)
{
int line, col, linewidth;
int y, u, v, yy, vr, ug, vg, ub;
int r, g, b;
const unsigned char *py, *pu, *pv;
linewidth = width >> 1;
py = src;
pu = py + (width * height);
pv = pu + (width * height) / 4;
y = *py++;
yy = y << 8;
u = *pu - 128;
ug = 88 * u;
ub = 454 * u;
v = *pv - 128;
vg = 183 * v;
vr = 359 * v;
for (line = 0; line < height; line++) {
for (col = 0; col < width; col++) {
r = (yy + vr) >> 8;
g = (yy - ug - vg) >> 8;
b = (yy + ub ) >> 8;
if (r < 0) r = 0;
if (r > 255) r = 255;
if (g < 0) g = 0;
if (g > 255) g = 255;
if (b < 0) b = 0;
if (b > 255) b = 255;
switch(push) {
case PUSH_RGB24:
*dst++ = r;
*dst++ = g;
*dst++ = b;
break;
case PUSH_BGR24:
*dst++ = b;
*dst++ = g;
*dst++ = r;
break;
case PUSH_RGB32:
*dst++ = r;
*dst++ = g;
*dst++ = b;
*dst++ = 0;
break;
case PUSH_BGR32:
*dst++ = b;
*dst++ = g;
*dst++ = r;
*dst++ = 0;
break;
}
y = *py++;
yy = y << 8;
if (col & 1) {
pu++;
pv++;
u = *pu - 128;
ug = 88 * u;
ub = 454 * u;
v = *pv - 128;
vg = 183 * v;
vr = 359 * v;
}
} /* ..for col */
if ((line & 1) == 0) { // even line: rewind
pu -= linewidth;
pv -= linewidth;
}
} /* ..for line */
}
void ccvt_420p_rgb24(int width, int height, const void *src, void *dst)
{
ccvt_420p(width, height, (const unsigned char *)src, (unsigned
char *)dst, PUSH_RGB24);
}
#########################
And here's what I have so far:
def yuv420p_to_rgb24(WIDTH, HEIGHT, source):
line, col, linewidth = 0,0,0
y,u,v,yy,vr,ug,vg,ub = 0,0,0,0,0,0,0,0
r,g,b = 0,0,0
linewidth = WIDTH >> 1
sourceframe = list(source)
py = 0
pu = py + (WIDTH * HEIGHT)
pv = pu + (WIDTH * HEIGHT) / 4
destination = []
destindex = 0
y = sourceframe[py]
py += 1
int(y)
yy = y << 8 # This is where it blows up
u = sourceframe[pu] - 128
ug = 88 * u
ub = 454 * u
v = sourceframe[pv] - 128
vg = 183 * v
vr = 359 * v
line = 0
while (line < HEIGHT):
col = 0
while (col < WIDTH):
r = (yy + vr) >> 8
g = (yy - ug - vg) >> 8
b = (yy + ub ) >> 8
if (r < 0):
r = 0
if (r > 255):
r = 255
if (g < 0):
g = 0
if (g > 255):
g = 255
if (b < 0):
b = 0
if (b > 255):
b = 255
destination[destindex] = r
destindex += 1
destination[destindex] = g
destindex += 1
destination[destindex] = b
destindex += 1
y = sourceframe[py]
py += 1
yy = y << 8
if (col & 1):
pu += 1
pv += 1
u = sourceframe[pu] - 128
ug = 88 * u
ub = 454 * u
v = sourceframe[pv] - 128
vg = 183 * v
vr = 359 * v
col += 1
#end while col
if ((line % 1) == 0): # even line: rewind
pu -= linewidth
pv -= linewidth
line += 1
#end while line
return destination