c语言yuv图片cb,jpeg_to_yuv函数的C实现

#define SCALEBITS 10

#define FIX(x)    ((int) ((x) * (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 */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值