Chinaunix首页 | 论坛 | 博客
  • 博客访问: 171519
  • 博文数量: 27
  • 博客积分: 533
  • 博客等级: 中士
  • 技术积分: 426
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-14 19:54
文章分类

全部博文(27)

文章存档

2013年(4)

2012年(18)

2011年(5)

分类: LINUX

2011-12-27 10:18:04

#define _GNU_SOURCE

#include
#include
#include
#include
#include
#include
#include
#include
#include

#include


#define SCALEBITS 10
#define FIX(x)    ((int) ((x) * (1<#define ONE_HALF  (1 << (SCALEBITS - 1))

#define RGB_TO_Y_CCIR(r, g, b) /
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + /
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)

#define RGB_TO_U_CCIR(r1, g1, b1, shift)/
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         /
     FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)

#define RGB_TO_V_CCIR(r1, g1, b1, shift)/
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           /
   FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)

/* declaration in stdio.h is there, but does not work */
extern FILE *fmemopen (void *__s, size_t __len, __const char *__modes) __THROW;


struct jpeg_error_manager
{
struct jpeg_error_mgr pub;    /* "public" fields */
jmp_buf setjmp_buffer;    /* for return to caller */
};

typedef struct jpeg_error_manager * my_error_ptr;

int jpeg_to_yuv(char *jpeg_buffer,unsigned char *yuv_buffer)
{
int a, i, k;
int width;
int height;
int r, g, b;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_manager jerr;
FILE *infile;                /* source file */
JSAMPARRAY buffer;            /* Output row buffer */
int row_stride;                /* physical row width in output buffer */
double y, u, v;
double cr, cg, cb, cu, cv;
unsigned char *y_ptr, *u_ptr, *v_ptr;
int xa, ya;
int yuv_buffer_length;
unsigned char *uptr;
double **up;
double **vp;
unsigned char *rgb24_buffer;
int tmp;
static int have_tried_flag; /* retried putimage on first image, else a white picture, why? */

a = 0; // -Wall

/* pick a color standard */
/* Panteltje's y spec */ cr = 0.3; cg = 0.59; cb = 0.11;
// /* ITU-601-1 Y spec */ cr = 0.299; cg = 0.587; cb = 0.114; /* used by ffplay and likely mplayer */
// /*  CIE-XYZ 1931 Kodak, postscript pdf Y spec */ cr = 0.298954; cg = 0.586434; cb = 0.114612;
// /* ITU-709 NTSC Y spec */ cr = 0.213; cg = 0.715; cb = 0.072;
// /* ITU/EBU 3213 PAL Y spec */ cr = 0.222; cg = 0.707; cb = 0.071;
/* U spec */
cu = .5 / (1.0 - cb);
/* V spec */
cv = .5 / (1.0 - cr);
//char *jpeg_buffer; // the jpeg picture data
//int content_length;
infile = (FILE *)fmemopen(jpeg_buffer, content_length, "r");

/* allocate and initialize JPEG decompression object */
/* We set up the normal JPEG error routines, then override error_exit. */
cinfo.err = jpeg_std_error(&jerr.pub);

if(setjmp(jerr.setjmp_buffer))
    {
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);

    /* Do not disconnect from the camera in case of some wrong bytes in jpeg buffer, but retry */
    return 1;
//    return 0;
    }

/* Now we can initialize the JPEG decompression object. */
jpeg_create_decompress(&cinfo);
/* specify data source (eg, a file) */
jpeg_stdio_src(&cinfo, infile);
/* read file parameters with jpeg_read_header() */
(void) jpeg_read_header(&cinfo, TRUE);
/*
set parameters for decompression
Don't need to change any of the defaults set by jpeg_read_header(),
so we do nothing here.
*/
/* Maybe use YUV directly, what about X11? */
//cinfo.out_color_space = JCS_YCbCr;
//cinfo.raw_data_out = TRUE;


/* Start decompressor */ (void) jpeg_start_decompress(&cinfo);

/*
Make an output work buffer of the right size.
JSAMPLEs per row in output buffer
*/
row_stride = cinfo.output_width * cinfo.output_components;
width = cinfo.output_width;
height = cinfo.output_height;

if(! rgb24_buffer)
    {
    rgb24_buffer = (unsigned char *)malloc(width * height * 3);
    if(! rgb24_buffer)
        {   
        fprintf(stderr, "jpg_to_yuv:malloc rgb24_buffer failed, aborting/n");

        exit(1);
        }   
    }

if(! yuv_header_send_flag)
    {
    /* send the mjpeg tools yuv stream header */

    /* stream stream header to get width and height and interlace */

    /*
    YUV4MPEG2 W720 H576 F25:1 I? A0:0 XM2AR002
    FRAME
    data
    */
    fprintf(stdout,/
    "YUV4MPEG2 W%d H%d F1:%d I? A0:0 XM2AR002/n", width, height, seconds_per_frame);

    yuv_header_send_flag = 1;
    }

/*
Make a one-row-high sample array that will go away when done with image
*/
buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

/*
while (scan lines remain to be read)
           jpeg_read_scanlines(...);
Here we use the library's state variable cinfo.output_scanline as the
loop counter, so that we don't have to keep track ourselves.
*/


if(cinfo.out_color_space == JCS_RGB)
    {
    uptr = rgb24_buffer;
    //WARNING programmer beware!!! cinfo.output_scanline starts at 1
    for(ya = 0; ya < cinfo.output_height; ya++)
        {
        /*
        jpeg_read_scanlines expects an array of pointers to scanlines.
        Here the array is only one element long, but you could ask for
        more than one scanline at a time if that's more convenient.
        */
        (void) jpeg_read_scanlines(&cinfo, buffer, 1);

        for(i = 0; i < row_stride; i += 3)
            {
            r = (int)buffer[0][i];
            g = (int)buffer[0][i + 1];
            b = (int)buffer[0][i + 2];

            *uptr++ = r;
            *uptr++ = g;
            *uptr++ = b;           
            } /* end for i */

        } /* end while all scan lines */
    } /* end if JCS_RGB */
else if(cinfo.out_color_space == 1)
    {
    uptr = rgb24_buffer;   
    for(ya = 0; ya < cinfo.output_height; ya++)
        {
        (void) jpeg_read_scanlines(&cinfo, buffer, 1);       
        for(i = 0; i < row_stride; i += 1)
            {
            g = (int)buffer[0][i];

            *uptr++ = g;
            *uptr++ = g;
            *uptr++ = g;           
            } /* end for i */
        } /* end while all scan lines */
    } /* end if color_space == 1 */
else
    {
    fprintf(stderr, "jpg_to_yuv:unsupported jpeg color space %d, aborting./n",  cinfo.out_color_space);
    exit(1);   
    }
   

yuv_buffer_length = (width * height) + ( (width / 2) * (height / 2) ) + ( (width / 2) * (height / 2) );

yuv_buffer = malloc(yuv_buffer_length);
if(! yuv_buffer)
    {
    fprintf(stderr, "jpg_to_yuv: process_jpeg_buffer(): could not allocate space for yuv_buffer, aborting./n");
    exit(1);
    }

/* rbgb24 to yuv and X */
/* for RGB to YUV */
y_ptr = yuv_buffer;
u_ptr = yuv_buffer + (width * height);
v_ptr = u_ptr + ( (width / 2) * (height / 2) );

// need bracket for gcc-2.95
    {
    /* reserve space for uv matrix */
    int i;
    double matrix_size = cinfo.output_height * width;
    if(! up)
        {
        up = malloc(cinfo.output_height * sizeof(double) );
        if(! up)
            {
            fprintf(stderr, "jpg_to__yuv: process_jpeg_buffer(): malloc(up) failed, aborting./n");
            exit(1);
            }

        for(i = 0; i < height; i++)
            {
            up[i] = malloc(width * sizeof(double)  );
            if(! up[i] )
                {
                fprintf(stderr, "jpg_to_yuv: process_jpeg_buffer(): malloc(up[%d]) failed, aborting./n", i);
                exit(1);
                }
            }
        }

    if(! vp)
        {
        vp = malloc(cinfo.output_height * sizeof(double) );
        if(! vp)
            {
            fprintf(stderr, "jpg_to_yuv: process_jpeg_buffer(): malloc(vp) failed, aborting./n");
            exit(1);
            }

        for(i = 0; i < height; i++)
            {
            vp[i] = malloc(width * sizeof(double)  );
            if(! vp[i] )
                {
                fprintf(stderr, "jpg_to_yuv: process_jpeg_buffer(): malloc(vp[%d]) failed, aborting./n", i);
                exit(1);
                }
       
            }
        }

    uptr = rgb24_buffer;
    k = 0;
    for(ya = 0; ya < height; ya++)
        {
        for(xa = 0; xa < width; xa++)
            {
            /* convert to YUV */
            r = (int)*uptr++;
            g = (int)*uptr++;
            b = (int)*uptr++;
            /* test yuv coding here */
//            y = cr * r + cg * g + cb * b;
//            y = (219.0 / 256.0) * y + 16.5;  /* nominal range: 16..235 */
            y = RGB_TO_Y_CCIR(r, g, b);
            *y_ptr = y;
            y_ptr++;
//            u = cu * (b - y) + 128.0;
//            u = (224.0 / 256.0) * u + 128.5; /* 16..240 */
            u = RGB_TO_U_CCIR(r, g, b, 0);
//            v = cv * (r - y) + 128.0;
//            v = (224.0 / 256.0) * v + 128.5; /* 16..240 */
            v = RGB_TO_V_CCIR(r, g, b, 0);
            /*
            0 0
            0 x
            */
            /* only on even rows and even columns do we output the average U and V for the 4 pixels */
            if(ya % 2)
                {
                if(xa % 2)
                    {
                    if(no_color_flag)
                        {
                        *u_ptr = 128.5;
                        *v_ptr = 128.5;
                        }
                    else
                        {   
                        *u_ptr = ( (up[ya - 1][xa - 1] + up[ya - 1][xa] + up[ya][xa -1] + u ) / 4.0);
                        *v_ptr = ( (vp[ya - 1][xa - 1] + vp[ya - 1][xa] + vp[ya][xa -1] + v ) / 4.0);
                        }

                    u_ptr++;
                    v_ptr++;

                    } /* end if odd pixel */

                } /* end if odd_line */
            /* fill uv matrix for lookback */
            up[ya][xa] = u;                 
            vp[ya][xa] = v;

            } /* end for xa */
        } /* end for ya */
    } /* end gcc-2.95 brackets */

/* output an mjpeg tools yuv frame header */
/*
FRAME-HEADER consists of
string "FRAME "  (note the space after the 'E')
unlimited number of ' ' separated TAGGED-FIELDs
'/n' line terminator
*/

fprintf(stdout, "FRAME/n");

/* output an mjpeg tools yuv frame */
/* write Y */
/* write Cb */
/* write Cv */
//unsigned char *yuv_buffer;

a = fwrite(yuv_buffer, sizeof(char), yuv_buffer_length, stdout);
if(a != yuv_buffer_length)
    {
    fprintf(stderr, "jpg_to_yuv: process_jpeg_buffer() output yuv: could only write %d of %d bytes, aborting./n",/
    a, yuv_buffer_length);
    exit(1);
    }

fflush(stdout);

/* Finish decompression */
(void) jpeg_finish_decompress(&cinfo);

/* Release JPEG decompression object */
jpeg_destroy_decompress(&cinfo);

fclose(infile);
/*
At this point you may want to check to see whether any corrupt-data
warnings occurred (test whether jerr.pub.num_warnings is nonzero).
*/
if(jerr.pub.num_warnings)
    {
    fprintf(stderr, "jpg_to_yuv: jpeg lib warnings=%ld occurred/n", jerr.pub.num_warnings);
    }

free(yuv_buffer);

return 1;
} /* end function process_jpeg_buffer */
阅读(4967) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

瑞莱克斯2015-04-15 09:41:32

能说一下思路吗???谢谢~~~

youzpp2014-09-16 14:08:36

楼主你的代码vc编译不过啊