binary string question

Dan Jones djones at shcorp.com
Sat Nov 8 01:36:52 CET 2003


On Fri, 2003-11-07 at 18:22, Peter Hansen wrote:
> Dan Jones wrote:
> > 
> > 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











More information about the Python-list mailing list