# 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 */