C implementation of the performance_to_yuv Function

Source: Internet
Author: User

# DEFINE _ gnu_source

# Include <stdio. h>
# Include <string. h>
# Include <stdlib. h>
# Include <time. h>
# Include <ctype. h>
# Include <errno. h>
# Include <unistd. h>
# Include <setjmp. h>
# Include <sys/STAT. h>

# Include <cmdlib. h>

# Define scalebits 10
# Define fix (x) (INT) (x) * (1 <scalebits) + 0.5 ))
# 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 performance_error_manager
{
Struct performance_error_mgr pub;/* "public" fields */
Jmp_buf setjmp_buffer;/* for return to caller */
};

Typedef struct performance_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 performance_decompress_struct Cinfo;
Struct performance_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 * pai_buffer; // The JPEG picture data
// Int content_length;
Infile = (File *) fmemopen (pai_buffer, content_length, "R ");

/* Allocate and initialize JPEG decompression object */
/* We set up the normal JPEG error routines, then override error_exit .*/
Cinfo. Err = maid (& Jerr. Pub );

If (setjmp (Jerr. setjmp_buffer ))
{
Pai_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 .*/
Pai_create_decompress (& Cinfo );
/* Specify data source (eg, a file )*/
Performance_stdio_src (& Cinfo, infile );
/* Read File parameters with pai_read_header ()*/
(Void) pai_read_header (& Cinfo, true );
/*
Set parameters for decompression
Don't need to change any of the defaults set by pai_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) pai_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 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)
Pai_read_scanlines (...);
Here we use the library's state variable Cinfo. output_scanline as
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 ++)
{
/*
Pai_read_scanlines expects an array of pointers to scanlines.
Here the array is only one element long, but you can ask
More than one scanline at a time if that's more convenient.
*/
(Void) pai_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) pai_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 (): cocould 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_pai_buffer (): malloc (up) failed, aborting./N ");
Exit (1 );
}

For (I = 0; 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_pai_buffer (): malloc (VP) failed, aborting./N ");
Exit (1 );
}

For (I = 0; I {
VP [I] = malloc (width * sizeof (double ));
If (! VP [I])
{
Fprintf (stderr, "jpg_to_yuv: process_pai_buffer (): malloc (VP [% d]) failed, aborting./N", I );
Exit (1 );
}

}
}

Uptr = rgb24_buffer;
K = 0;
For (YA = 0; 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
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 (! = Yuv_buffer_length)
{
Fprintf (stderr, "jpg_to_yuv: process_0000_buffer () Output YUV: cocould only write % d of % d bytes, aborting./N ",/
A, yuv_buffer_length );
Exit (1 );
}

Fflush (stdout );

/* Finish decompression */
(Void) pai_finish_decompress (& Cinfo );

/* Release JPEG decompression object */
Pai_destroy_decompress (& Cinfo );

Fclose (infile );
/*
At this point you may be want to check to see whether any other upt-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 */

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.