Esempio n. 1
0
static int v4l2_probe_iomode (zbar_video_t *vdo)
{
    struct v4l2_requestbuffers rb;
    memset(&rb, 0, sizeof(rb));
    rb.count = vdo->num_images; /* FIXME workaround broken drivers */
    rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if(vdo->iomode == VIDEO_MMAP)
        rb.memory = V4L2_MEMORY_MMAP;
    else
        rb.memory = V4L2_MEMORY_USERPTR;

    if(ioctl(vdo->fd, VIDIOC_REQBUFS, &rb) < 0) {
        if(vdo->iomode)
            return(err_capture_int(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                                   "unsupported iomode requested (%d)",
                                   vdo->iomode));
        else if(errno != EINVAL)
            return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                               "querying streaming mode (VIDIOC_REQBUFS)"));
#ifdef HAVE_SYS_MMAN_H
        vdo->iomode = VIDEO_MMAP;
#endif
    }
    else {
        if(!vdo->iomode)
            vdo->iomode = VIDEO_USERPTR;
        if(rb.count)
            vdo->num_images = rb.count;
    }
    return(0);
}
Esempio n. 2
0
static inline int v4l1_set_format (zbar_video_t *vdo,
                                   uint32_t fmt)
{
    struct video_picture vpic;
    memset(&vpic, 0, sizeof(vpic));
    if(ioctl(vdo->fd, VIDIOCGPICT, &vpic) < 0)
        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                           "querying video format (VIDIOCGPICT)"));

    vdo->palette = 0;
    int ifmt;
    for(ifmt = 1; ifmt <= VIDEO_PALETTE_YUV410P; ifmt++)
        if(v4l1_formats[ifmt].format == fmt)
            break;
    if(!fmt || ifmt >= VIDEO_PALETTE_YUV410P)
        return(err_capture_int(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                               "invalid v4l1 format: %x", fmt));

    vpic.palette = ifmt;
    vpic.depth = v4l1_formats[ifmt].bpp;
    if(ioctl(vdo->fd, VIDIOCSPICT, &vpic) < 0)
        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                           "setting format (VIDIOCSPICT)"));

    memset(&vpic, 0, sizeof(vpic));
    if(ioctl(vdo->fd, VIDIOCGPICT, &vpic) < 0)
        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                           "querying video format (VIDIOCGPICT)"));

    if(vpic.palette != ifmt || vpic.depth != v4l1_formats[ifmt].bpp) {
        fprintf(stderr,
                "WARNING: set v4l1 palette %d which should have depth %d bpp\n"
                "    but probed palette %d with depth %d bpp?"
                "  ...continuing anyway\n",
                ifmt, v4l1_formats[ifmt].bpp, vpic.palette, vpic.depth);
        err_capture_int(vdo, SEV_WARNING, ZBAR_ERR_INVALID, __func__,
                        "driver format (%x) inconsistency", fmt);
    }
    vdo->format = fmt;
    vdo->palette = ifmt;
    vdo->datalen = (vdo->width * vdo->height * v4l1_formats[ifmt].bpp + 7) >> 3;

    zprintf(1, "set new format: %.4s(%08x) depth=%d palette=%d size=0x%lx\n",
            (char*)&vdo->format, vdo->format, vpic.depth, vdo->palette,
            vdo->datalen);
    return(0);
}
Esempio n. 3
0
static int v4l2_set_format (zbar_video_t *vdo,
                            uint32_t fmt)
{
    struct v4l2_format vfmt;
    struct v4l2_pix_format *vpix = &vfmt.fmt.pix;
    memset(&vfmt, 0, sizeof(vfmt));
    vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    vpix->width = vdo->width;
    vpix->height = vdo->height;
    vpix->pixelformat = fmt;
    vpix->field = V4L2_FIELD_NONE;
    int rc = 0;
    if((rc = ioctl(vdo->fd, VIDIOC_S_FMT, &vfmt)) < 0) {
        /* several broken drivers return an error if we request
         * no interlacing (NB v4l2 spec violation)
         * ...try again with an interlaced request
         */
        zprintf(1, "VIDIOC_S_FMT returned %d(%d), trying interlaced...\n",
                rc, errno);

        /* FIXME this might be _ANY once we can de-interlace */
        vpix->field = V4L2_FIELD_INTERLACED;

        if(ioctl(vdo->fd, VIDIOC_S_FMT, &vfmt) < 0)
            return(err_capture_int(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                                   "setting format %x (VIDIOC_S_FMT)", fmt));

        zprintf(0, "WARNING: broken driver returned error when non-interlaced"
                " format requested\n");
    }

    struct v4l2_format newfmt;
    struct v4l2_pix_format *newpix = &newfmt.fmt.pix;
    memset(&newfmt, 0, sizeof(newfmt));
    newfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if(ioctl(vdo->fd, VIDIOC_G_FMT, &newfmt) < 0)
        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                           "querying format (VIDIOC_G_FMT)"));

    if(newpix->field != V4L2_FIELD_NONE)
        err_capture(vdo, SEV_WARNING, ZBAR_ERR_INVALID, __func__,
                    "video driver only supports interlaced format,"
                    " vertical scanning may not work");

    if(newpix->pixelformat != fmt
       /* FIXME bpl/bpp checks? */)
        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                           "video driver can't provide compatible format"));

    vdo->format = fmt;
    vdo->width = newpix->width;
    vdo->height = newpix->height;
    vdo->datalen = newpix->sizeimage;

    zprintf(1, "set new format: %.4s(%08x) %u x %u (0x%lx)\n",
            (char*)&vdo->format, vdo->format, vdo->width, vdo->height,
            vdo->datalen);
    return(0);
}
Esempio n. 4
0
static int vfw_set_format (zbar_video_t *vdo,
                           uint32_t fmt)
{
    const zbar_format_def_t *fmtdef = _zbar_format_lookup(fmt);
    if(!fmtdef->format)
        return(err_capture_int(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                               "unsupported vfw format: %x", fmt));

    BITMAPINFOHEADER *bih = vdo->state->bih;
    assert(bih);
    bih->biWidth = vdo->width;
    bih->biHeight = vdo->height;
    switch(fmtdef->group) {
    case ZBAR_FMT_GRAY:
        bih->biBitCount = 8;
        break;
    case ZBAR_FMT_YUV_PLANAR:
    case ZBAR_FMT_YUV_PACKED:
    case ZBAR_FMT_YUV_NV:
        bih->biBitCount = 8 + (16 >> (fmtdef->p.yuv.xsub2 + fmtdef->p.yuv.ysub2));
        break;
    case ZBAR_FMT_RGB_PACKED:
        bih->biBitCount = fmtdef->p.rgb.bpp * 8;
        break;
    default:
        bih->biBitCount = 0;
    }
    bih->biClrUsed = bih->biClrImportant = 0;
    bih->biCompression = fmt;

    zprintf(8, "seting format: %.4s(%08x) " BIH_FMT "\n",
            (char*)&fmt, fmt, BIH_FIELDS(bih));

    if(!capSetVideoFormat(vdo->state->hwnd, bih, vdo->state->bi_size))
        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                           "setting video format"));

    if(!capGetVideoFormat(vdo->state->hwnd, bih, vdo->state->bi_size))
        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                           "getting video format"));

    if(bih->biCompression != fmt)
        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                           "video format set ignored"));

    vdo->format = fmt;
    vdo->width = bih->biWidth;
    vdo->height = bih->biHeight;
    vdo->datalen = bih->biSizeImage;

    zprintf(4, "set new format: %.4s(%08x) " BIH_FMT "\n",
            (char*)&fmt, fmt, BIH_FIELDS(bih));
    return(0);
}
Esempio n. 5
0
static inline int ximage_init (zbar_window_t *w,
                               zbar_image_t *img)
{
    if(w->img.x) {
        free(w->img.x);
        w->img.x = NULL;
    }
    if(w->src_format != img->format &&
       w->format != img->format) {
        _zbar_best_format(img->format, &w->format, w->formats);
        if(!w->format) {
            err_capture_int(w, SEV_ERROR, ZBAR_ERR_UNSUPPORTED, __func__,
                            "no conversion from %x to supported formats",
                            img->format);
            return(-1);
        }
        w->src_format = img->format;
    }
    XImage *ximg = w->img.x = calloc(1, sizeof(XImage));
    ximg->width = img->width;
    ximg->height = img->height;
    ximg->format = ZPixmap;
    ximg->byte_order = LSBFirst;
    ximg->bitmap_unit = 8;
    ximg->bitmap_bit_order = MSBFirst;
    ximg->bitmap_pad = 8;

    const zbar_format_def_t *fmt = _zbar_format_lookup(w->format);
    if(fmt->group == ZBAR_FMT_RGB_PACKED) {
        ximg->depth = ximg->bits_per_pixel = fmt->p.rgb.bpp << 3;
        ximg->red_mask =
            (0xff >> RGB_SIZE(fmt->p.rgb.red))
            << RGB_OFFSET(fmt->p.rgb.red);
        ximg->green_mask =
            (0xff >> RGB_SIZE(fmt->p.rgb.green))
            << RGB_OFFSET(fmt->p.rgb.green);
        ximg->blue_mask =
            (0xff >> RGB_SIZE(fmt->p.rgb.blue))
            << RGB_OFFSET(fmt->p.rgb.blue);
    }
Esempio n. 6
0
inline int zbar_window_redraw (zbar_window_t *w)
{
    if(window_lock(w))
        return(-1);
    if(!w->display || _zbar_window_begin(w)) {
        (void)window_unlock(w);
        return(-1);
    }

    int rc = 0;
    zbar_image_t *img = w->image;
    if(w->init && w->draw_image && img) {
        int format_change = (w->src_format != img->format &&
                             w->format != img->format);
        if(format_change) {
            _zbar_best_format(img->format, &w->format, w->formats);
            if(!w->format)
                rc = err_capture_int(w, SEV_ERROR, ZBAR_ERR_UNSUPPORTED, __func__,
                                     "no conversion from %x to supported formats",
                                     img->format);
            w->src_format = img->format;
        }

        if(!rc && (format_change || !w->scaled_size.x || !w->dst_width)) {
            zprintf(24, "init: src=%.4s(%08lx) %dx%d dst=%.4s(%08lx) %dx%d\n",
                    (char*)&w->src_format, w->src_format,
                    w->src_width, w->src_height,
                    (char*)&w->format, w->format,
                    w->dst_width, w->dst_height);
            if(!w->dst_width) {
                w->src_width = img->width;
                w->src_height = img->height;
            }

            point_t size = { w->width, w->height };
            if(size.x > w->max_width)
                size.x = w->max_width;
            if(size.y > w->max_height)
                size.y = w->max_height;

            if(size.x * w->src_height < size.y * w->src_width) {
                w->scale_num = size.x;
                w->scale_den = w->src_width;
            }
            else {
                w->scale_num = size.y;
                w->scale_den = w->src_height;
            }

            rc = w->init(w, img, format_change);

            if(!rc) {
                size.x = w->src_width;
                size.y = w->src_height;
                w->scaled_size = size = window_scale_pt(w, size);
                w->scaled_offset.x = ((int)w->width - size.x) / 2;
                w->scaled_offset.y = ((int)w->height - size.y) / 2;
                zprintf(24, "scale: src=%dx%d win=%dx%d by %d/%d => %dx%d @%d,%d\n",
                        w->src_width, w->src_height, w->width, w->height,
                        w->scale_num, w->scale_den,
                        size.x, size.y, w->scaled_offset.x, w->scaled_offset.y);
            }
            else {
                /* unable to display this image */
                _zbar_image_refcnt(img, -1);
                w->image = img = NULL;
            }
        }

        if(!rc &&
                (img->format != w->format ||
                 img->width != w->dst_width ||
                 img->height != w->dst_height)) {
            /* save *converted* image for redraw */
            zprintf(48, "convert: %.4s(%08lx) %dx%d => %.4s(%08lx) %dx%d\n",
                    (char*)&img->format, img->format, img->width, img->height,
                    (char*)&w->format, w->format, w->dst_width, w->dst_height);
            w->image = zbar_image_convert_resize(img, w->format,
                                                 w->dst_width, w->dst_height);
            w->image->syms = img->syms;
            if(img->syms)
                zbar_symbol_set_ref(img->syms, 1);
            zbar_image_destroy(img);
            img = w->image;
        }

        if(!rc) {
            rc = w->draw_image(w, img);

            point_t org = w->scaled_offset;
            if(org.x > 0) {
                point_t p = { 0, org.y };
                point_t s = { org.x, w->scaled_size.y };
                _zbar_window_fill_rect(w, 0, p, s);
                s.x = w->width - w->scaled_size.x - s.x;
                if(s.x > 0) {
                    p.x = w->width - s.x;
                    _zbar_window_fill_rect(w, 0, p, s);
                }
            }
            if(org.y > 0) {
                point_t p = { 0, 0 };
                point_t s = { w->width, org.y };
                _zbar_window_fill_rect(w, 0, p, s);
                s.y = w->height - w->scaled_size.y - s.y;
                if(s.y > 0) {
                    p.y = w->height - s.y;
                    _zbar_window_fill_rect(w, 0, p, s);
                }
            }
        }
        if(!rc)
            rc = window_draw_overlay(w);
    }
    else
        rc = 1;

    if(rc)
        rc = _zbar_window_draw_logo(w);

    _zbar_window_end(w);
    (void)window_unlock(w);
    return(rc);
}