Example #1
0
void zbar_video_destroy (zbar_video_t *vdo)
{
    if(vdo->intf != VIDEO_INVALID)
        zbar_video_open(vdo, NULL);
    if(vdo->images) {
        int i;
        for(i = 0; i < ZBAR_VIDEO_IMAGES_MAX; i++)
            if(vdo->images[i])
                _zbar_image_free(vdo->images[i]);
        free(vdo->images);
    }
    while(vdo->shadow_image) {
        zbar_image_t *img = vdo->shadow_image;
        vdo->shadow_image = img->next;
        free((void*)img->data);
        img->data = NULL;
        free(img);
    }
    if(vdo->buf)
        free(vdo->buf);
    if(vdo->formats)
        free(vdo->formats);
    err_cleanup(&vdo->err);
    _zbar_mutex_destroy(&vdo->qlock);

#ifdef HAVE_LIBJPEG
    if(vdo->jpeg_img) {
        zbar_image_destroy(vdo->jpeg_img);
        vdo->jpeg_img = NULL;
    }
    if(vdo->jpeg) {
        _zbar_jpeg_decomp_destroy(vdo->jpeg);
        vdo->jpeg = NULL;
    }
#endif
    free(vdo);
}
Example #2
0
/* invoke libjpeg to decompress JPEG format to luminance plane */
void _zbar_convert_jpeg_to_y (zbar_image_t *dst,
                              const zbar_format_def_t *dstfmt,
                              const zbar_image_t *src,
                              const zbar_format_def_t *srcfmt)
{
    /* create decompressor, or use cached video stream decompressor */
    errenv_t *jerr = NULL;
    j_decompress_ptr cinfo;
    if(!src->src)
        cinfo = _zbar_jpeg_decomp_create();
    else {
        cinfo = src->src->jpeg;
        assert(cinfo);
    }
    if(!cinfo)
        goto error;

    jerr = (errenv_t*)cinfo->err;
    jerr->valid = 1;
    if(setjmp(jerr->env)) {
        /* FIXME TBD save error to src->src->err */
        (*cinfo->err->output_message)((j_common_ptr)cinfo);
        if(dst->data) {
            free((void*)dst->data);
            dst->data = NULL;
        }
        dst->datalen = 0;
        goto error;
    }

    /* setup input image */
    if(!cinfo->src) {
        cinfo->src = calloc(1, sizeof(zbar_src_mgr_t));
        cinfo->src->init_source = init_source;
        cinfo->src->fill_input_buffer = fill_input_buffer;
        cinfo->src->skip_input_data = skip_input_data;
        cinfo->src->resync_to_restart = jpeg_resync_to_restart;
        cinfo->src->term_source = term_source;
    }
    cinfo->src->next_input_byte = NULL;
    cinfo->src->bytes_in_buffer = 0;
    ((zbar_src_mgr_t*)cinfo->src)->img = src;

    int rc = jpeg_read_header(cinfo, TRUE);
    zprintf(30, "header: %s\n", (rc == 2) ? "tables-only" : "normal");

    /* supporting color with jpeg became...complicated,
     * so we skip that for now
     */
    cinfo->out_color_space = JCS_GRAYSCALE;

    /* FIXME set scaling based on dst->{width,height}
     * then pass bigger buffer...
     */

    jpeg_start_decompress(cinfo);

    /* adjust dst image parameters to match(?) decompressor */
    if(dst->width < cinfo->output_width)
        dst->width = cinfo->output_width;
    if(dst->height < cinfo->output_height)
        dst->height = cinfo->output_height;
    unsigned long datalen = (cinfo->output_width *
                             cinfo->output_height *
                             cinfo->out_color_components);

    zprintf(24, "dst=%dx%d %lx src=%dx%d %lx dct=%x\n",
            dst->width, dst->height, dst->datalen,
            src->width, src->height, src->datalen, cinfo->dct_method);
    if(!dst->data) {
        dst->datalen = datalen;
        dst->data = malloc(dst->datalen);
        dst->cleanup = zbar_image_free_data;
    }
    else
        assert(datalen <= dst->datalen);
    if(!dst->data) return;

    unsigned bpl = dst->width * cinfo->output_components;
    JSAMPROW buf = (void*)dst->data;
    JSAMPARRAY line = &buf;
    for(; cinfo->output_scanline < cinfo->output_height; buf += bpl) {
        jpeg_read_scanlines(cinfo, line, 1);
        /* FIXME pad out to dst->width */
    }

    /* FIXME always do this? */
    jpeg_finish_decompress(cinfo);

 error:
    if(jerr)
        jerr->valid = 0;
    if(!src->src && cinfo)
        /* cleanup only if we allocated locally */
        _zbar_jpeg_decomp_destroy(cinfo);
}