Commit c3d99649 authored by Arnaud Blanchard's avatar Arnaud Blanchard
Browse files

Add management og YUYV

parent 31aeb6bf
......@@ -59,755 +59,781 @@ static int g_source_remove_pt=G_SOURCE_REMOVE;
#define SWAP_RGBA_TO_CAIRO_ARGB32(x) ((((x) & 0x000000FF) << 16) | (((x) & 0x00FF0000) >> 16) | ((x) & 0xFF00FF00) )
static void toggle_fullscreen(GtkWidget *widget, GdkEventWindowState *event, gpointer user_data){
if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN ){
gtk_widget_hide(toolbar);
gtk_widget_hide(general_statusbar);
}
else{
gtk_widget_show(toolbar);
gtk_widget_show(general_statusbar);
}
if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN ){
gtk_widget_hide(toolbar);
gtk_widget_hide(general_statusbar);
}
else{
gtk_widget_show(toolbar);
gtk_widget_show(general_statusbar);
}
}
void* create_RGBA_from_YUYV(void *widget)
{
int Y, Cb, Cr;
int i, j;
float G_tmp;
static uchar R[256], B;
(void)widget;
if (RGBA_from_YUYV == NULL)
{
RGBA_from_YUYV= MANY_ALLOCATIONS(256*256*256, uint32_t);
FOR_INV(Y, 256)
{
FOR_INV(j,256) R[j]= CLIP_UCHAR(Y+1.13983*(j-128)); //It does not depend on Cb
FOR_INV(Cb, 256)
{
B = CLIP_UCHAR(Y+2.03211*(Cb-128)); // It does not depend on Cr
G_tmp = - 0.58060*(Cb-128);
FOR_INV(Cr, 256)
{
i = Y + (Cb << 8) + (Cr << 16);
// Version Wikipedia
RGBA_from_YUYV[i] = (R[Cr]<<16) + (((uchar)CLIP_UCHAR(Y-0.39465*(Cr-128) + G_tmp))<< 8)+ B + (255<<24);
}
}
}
}
return NULL;
int Y, Cb, Cr;
int i, j;
float G_tmp;
static uchar R[256], B;
(void)widget;
if (RGBA_from_YUYV == NULL)
{
RGBA_from_YUYV= MANY_ALLOCATIONS(256*256*256, uint32_t);
FOR_INV(Y, 256)
{
FOR_INV(j,256) R[j]= CLIP_UCHAR(Y+1.13983*(j-128)); //It does not depend on Cb
FOR_INV(Cb, 256)
{
B = CLIP_UCHAR(Y+2.03211*(Cb-128)); // It does not depend on Cr
G_tmp = - 0.58060*(Cb-128);
FOR_INV(Cr, 256)
{
i = Y + (Cb << 8) + (Cr << 16);
// Version Wikipedia
RGBA_from_YUYV[i] = (R[Cr]<<16) + (((uchar)CLIP_UCHAR(Y-0.39465*(Cr-128) + G_tmp))<< 8)+ B + (255<<24);
}
}
}
}
return NULL;
}
void init_false_colors()
{
int i, val;
int min;
FOR_INV(i, 256)
{
min=(int)(i*6/256)*256/6;
if ((i-min) > 256/6) min++;
val=(i-min)*6;
switch (i*6/256)
{
case 0:false_colors[i]=(val)+(255<<24);
break;
case 1:false_colors[i]=255+(val<<8)+(255<<24);
break;
case 2:false_colors[i]=(255-val)+(255<<8)+(255<<24);
break;
case 3:false_colors[i]=(255<<8)+(val<<16)+(255<<24);
break;
case 4:false_colors[i]=((255-val)<<8)+(255<<16)+(255<<24);
break;
case 5:false_colors[i]=(255<<16)+(val)+(val<<8)+(255<<24);
break;
}
}
int i, val;
int min;
FOR_INV(i, 256)
{
min=(int)(i*6/256)*256/6;
if ((i-min) > 256/6) min++;
val=(i-min)*6;
switch (i*6/256)
{
case 0:false_colors[i]=(val)+(255<<24);
break;
case 1:false_colors[i]=255+(val<<8)+(255<<24);
break;
case 2:false_colors[i]=(255-val)+(255<<8)+(255<<24);
break;
case 3:false_colors[i]=(255<<8)+(val<<16)+(255<<24);
break;
case 4:false_colors[i]=((255-val)<<8)+(255<<16)+(255<<24);
break;
case 5:false_colors[i]=(255<<16)+(val)+(val<<8)+(255<<24);
break;
}
}
}
static void init_color_maps(){
int i;
if (RGBA_from_YUYV==NULL) create_RGBA_from_YUYV(NULL);
FOR_INV(i, 256){
gray_colors[i]= i+(i<<8)+(i<<16)+(255<<24);
u_colors[i]= RGBA_from_YUYV[128+(i<<8)+(128<<16)]+(255<<24);
v_colors[i]=RGBA_from_YUYV[127+(127<<8)+(i<<16)];
r_colors[i]= 128+(128<<8)+(i<<16)+(255<<24);
g_colors[i]= 128+(i<<8)+(128<<16)+(255<<24);
b_colors[i]= i+(128<<8)+(128<<16)+(255<<24);
}
init_false_colors();
int i;
if (RGBA_from_YUYV==NULL) create_RGBA_from_YUYV(NULL);
FOR_INV(i, 256){
gray_colors[i]= i+(i<<8)+(i<<16)+(255<<24);
u_colors[i]= RGBA_from_YUYV[128+(i<<8)+(128<<16)]+(255<<24);
v_colors[i]=RGBA_from_YUYV[127+(127<<8)+(i<<16)];
r_colors[i]= 128+(128<<8)+(i<<16)+(255<<24);
g_colors[i]= 128+(i<<8)+(128<<16)+(255<<24);
b_colors[i]= i+(128<<8)+(128<<16)+(255<<24);
}
init_false_colors();
}
/** Gtk cannot display a black and white image, therefore we convert it before updating it*/
gboolean update_Y800_image(GtkImage *image, GdkFrameClock *, gpointer pointer_statusbar)
{
int i, x, y, j;
double sx, sy;
uint32_t *values;
char text[64];
if (blc_command_loop_start()==0) exit(0);
values = (uint32_t*)image_buffer;
if (channel->type=='UIN8') FOR_INV(i, channel->size) values[i]=color_map[channel->uchars[i]];
else if (channel->type=='FL32') FOR_INV(i, channel->size/sizeof(float)) values[i]=color_map[CLIP_UCHAR(channel->floats[i]*256-0.5f)];
else EXIT_ON_ARRAY_ERROR(channel, "Type not amanaged");
gtk_image_set_from_surface(image, image_surface);
gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(image)), pointer_device, &x, &y, NULL);
cairo_surface_get_device_scale(image_surface, &sx, &sy);
i=x*sx;
j=y*sy;
if (i<width && j<height && i>=0 && j>=0)
{
if (channel->type=='UIN8') SPRINTF(text, "%4d,%4d: Y:%3d", i,j, channel->uchars[i+j*width]);
else if (channel->type=='FL32') SPRINTF(text, "%4d,%4d: Y:%.3f", i,j, channel->floats[i+j*width]);
gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text);
}
iterations++;
blc_command_loop_end();
return blc_status;
int i, x, y, j;
double sx, sy;
uint32_t *values;
char text[64];
if (blc_command_loop_start()==0) exit(0);
values = (uint32_t*)image_buffer;
if (channel->type=='UIN8') FOR_INV(i, channel->size) values[i]=color_map[channel->uchars[i]];
else if (channel->type=='FL32') FOR_INV(i, channel->size/sizeof(float)) values[i]=color_map[CLIP_UCHAR(channel->floats[i]*256-0.5f)];
else EXIT_ON_ARRAY_ERROR(channel, "Type not managed");
gtk_image_set_from_surface(image, image_surface);
gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(image)), pointer_device, &x, &y, NULL);
cairo_surface_get_device_scale(image_surface, &sx, &sy);
i=x*sx;
j=y*sy;
if (i<width && j<height && i>=0 && j>=0)
{
if (channel->type=='UIN8') SPRINTF(text, "%4d,%4d: Y:%3d", i,j, channel->uchars[i+j*width]);
else if (channel->type=='FL32') SPRINTF(text, "%4d,%4d: Y:%.3f", i,j, channel->floats[i+j*width]);
gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text);
}
iterations++;
blc_command_loop_end();
return blc_status;
}
gboolean update_RGB3_image(GtkImage *image, GdkFrameClock *, gpointer pointer_statusbar)
{
char text[NAME_MAX];
double sx, sy;
int x, y, i=0, j=0;
int R, G, B;
gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(image)), pointer_device, &x, &y, NULL);
cairo_surface_get_device_scale(image_surface, &sx, &sy);
while(i!=channel->size)
{
image_buffer[j++]=channel->uchars[i+2];
image_buffer[j++]=channel->uchars[i+1];
image_buffer[j++]=channel->uchars[i];
j++;
i+=3;
}
i=x*sx;
j=y*sy;
if (i<width && j<height && i>=0 && j>=0)
{
if (mouse_channel.fd!=-1)
{
mouse_channel.uints32[0]=i;
mouse_channel.uints32[1]=j;
gdk_device_get_state(pointer_device, gtk_widget_get_window(GTK_WIDGET(image)), NULL, (GdkModifierType*)(&mouse_channel.uints32[2]));
}
R=channel->uchars[i*4+j*width*3];
G=channel->uchars[i*4+j*width*3+1];
B=channel->uchars[i*4+j*width*3+2];
SPRINTF(text, "%4d,%4d : R:%3d,G:%3d,B:%3d", i, j, R, G, B);
gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text);
}
gtk_image_set_from_surface(image, image_surface);
iterations++;
return G_SOURCE_CONTINUE;
char text[NAME_MAX];
double sx, sy;
int x, y, i=0, j=0;
int R, G, B;
gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(image)), pointer_device, &x, &y, NULL);
cairo_surface_get_device_scale(image_surface, &sx, &sy);
while(i!=channel->size)
{
image_buffer[j++]=channel->uchars[i+2];
image_buffer[j++]=channel->uchars[i+1];
image_buffer[j++]=channel->uchars[i];
j++;
i+=3;
}
i=x*sx;
j=y*sy;
if (i<width && j<height && i>=0 && j>=0)
{
if (mouse_channel.fd!=-1)
{
mouse_channel.uints32[0]=i;
mouse_channel.uints32[1]=j;
gdk_device_get_state(pointer_device, gtk_widget_get_window(GTK_WIDGET(image)), NULL, (GdkModifierType*)(&mouse_channel.uints32[2]));
}
R=channel->uchars[i*4+j*width*3];
G=channel->uchars[i*4+j*width*3+1];
B=channel->uchars[i*4+j*width*3+2];
SPRINTF(text, "%4d,%4d : R:%3d,G:%3d,B:%3d", i, j, R, G, B);
gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text);
}
gtk_image_set_from_surface(image, image_surface);
iterations++;
return G_SOURCE_CONTINUE;
}
gboolean update_RGBA_image(GtkImage *image, GdkFrameClock *, gpointer pointer_statusbar)
{
double sx, sy;
int x, y;
int i, j=0;
char text[NAME_MAX];
int R, G, B, A;
gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(image)), pointer_device, &x, &y, NULL);
cairo_surface_get_device_scale(image_surface, &sx, &sy);
FOR_INV(i, channel->size/4) ((uint32_t*)image_buffer)[i]=SWAP_RGBA_TO_CAIRO_ARGB32(channel->uints32[i]);
i=x*sx;
j=y*sy;
if (i<width && j<height && i>=0 && j>=0)
{
if (mouse_channel.fd!=-1)
{
mouse_channel.uints32[0]=i;
mouse_channel.uints32[1]=j;
gdk_device_get_state(pointer_device, gtk_widget_get_window(GTK_WIDGET(image)), NULL, (GdkModifierType*)(&mouse_channel.uints32[2]));
}
R=channel->uchars[i*4+j*width*4];
G=channel->uchars[i*4+j*width*4+1];
B=channel->uchars[i*4+j*width*4+2];
A=channel->uchars[i*4+j*width*4+3];
SPRINTF(text, "%4d,%4d: R:%d G:%d B:%d A:%d", i, j, R, G, B, A);
gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text);
}
gtk_image_set_from_surface(image, image_surface);
iterations++;
return G_SOURCE_CONTINUE;
double sx, sy;
int x, y;
int i, j=0;
char text[NAME_MAX];
int R, G, B, A;
gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(image)), pointer_device, &x, &y, NULL);
cairo_surface_get_device_scale(image_surface, &sx, &sy);
FOR_INV(i, channel->size/4) ((uint32_t*)image_buffer)[i]=SWAP_RGBA_TO_CAIRO_ARGB32(channel->uints32[i]);
i=x*sx;
j=y*sy;
if (i<width && j<height && i>=0 && j>=0)
{
if (mouse_channel.fd!=-1)
{
mouse_channel.uints32[0]=i;
mouse_channel.uints32[1]=j;
gdk_device_get_state(pointer_device, gtk_widget_get_window(GTK_WIDGET(image)), NULL, (GdkModifierType*)(&mouse_channel.uints32[2]));
}
R=channel->uchars[i*4+j*width*4];
G=channel->uchars[i*4+j*width*4+1];
B=channel->uchars[i*4+j*width*4+2];
A=channel->uchars[i*4+j*width*4+3];
SPRINTF(text, "%4d,%4d: R:%d G:%d B:%d A:%d", i, j, R, G, B, A);
gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text);
}
gtk_image_set_from_surface(image, image_surface);
iterations++;
return G_SOURCE_CONTINUE;
}
// Soon we should the implementation of blc_image */
void jpeg_error(j_common_ptr cinfo, int msg_level)
{
(void) msg_level;
cinfo->err->num_warnings++;
(void) msg_level;
cinfo->err->num_warnings++;
}
gboolean update_JPEG_image(GtkImage *image, GdkFrameClock *frame_clock, blc_channel *channel)
{
JSAMPROW row_pt[1];
GdkPixbuf *pixbuf;
int row_stride;
uchar *pixels;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
(void) frame_clock;
pixbuf = gtk_image_get_pixbuf(image);
pixels = gdk_pixbuf_get_pixels(pixbuf);
cinfo.err = jpeg_std_error(&jerr);
cinfo.err->emit_message = jpeg_error;
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo, (uchar*) channel->data, channel->size);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
row_stride = cinfo.output_width * cinfo.output_components;
row_pt[0] = pixels;
while (cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, row_pt, 1);
row_pt[0] += row_stride;
}
if (cinfo.err->num_warnings != 0)
{
PRINT_WARNING("Drop image : %s", cinfo.err->jpeg_message_table[cinfo.err->last_jpeg_message]);
cinfo.err->num_warnings = 0;
}
gtk_image_set_from_pixbuf(image, pixbuf);
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return G_SOURCE_CONTINUE;
JSAMPROW row_pt[1];
GdkPixbuf *pixbuf;
int row_stride;
uchar *pixels;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
(void) frame_clock;
pixbuf = gtk_image_get_pixbuf(image);
pixels = gdk_pixbuf_get_pixels(pixbuf);
cinfo.err = jpeg_std_error(&jerr);
cinfo.err->emit_message = jpeg_error;
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo, (uchar*) channel->data, channel->size);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
row_stride = cinfo.output_width * cinfo.output_components;
row_pt[0] = pixels;
while (cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, row_pt, 1);
row_pt[0] += row_stride;
}
if (cinfo.err->num_warnings != 0)
{
PRINT_WARNING("Drop image : %s", cinfo.err->jpeg_message_table[cinfo.err->last_jpeg_message]);
cinfo.err->num_warnings = 0;
}
gtk_image_set_from_pixbuf(image, pixbuf);
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return G_SOURCE_CONTINUE;
}
// 4:2:2
gboolean update_YUYV_image(GtkImage *image, GdkFrameClock *frame_clock, blc_channel *channel)
gboolean update_YUYV_image(GtkImage *image, GdkFrameClock *frame_clock, void*)
{
int i, j;
uchar *data = (uchar*) channel->data;
uint32_t *pixels;
int Y, Cb = 128, Cr = 128;
(void) frame_clock;
pixels = (uint32_t*)image_buffer;
i = 0;
while (i != (int) channel->size)
{
Y = data[i++];
Cb = data[i++];
j = Y + (Cb << 8) + (Cr << 16);
pixels[0]=RGBA_from_YUYV[j];
Y = data[i++];
Cr = data[i++];
j = Y + (Cb << 8) + (Cr << 16);
pixels[1]=RGBA_from_YUYV[j];
pixels+=2;
}
gtk_image_set_from_surface(image, image_surface);
return G_SOURCE_CONTINUE;
int i, j;
uchar *data = (uchar*) channel->data;
uint32_t *pixels;
int Y, Cb = 128, Cr = 128;
(void) frame_clock;
pixels = (uint32_t*)image_buffer;
if (blc_command_loop_start()==0) exit(0);
i = 0;
while (i != (int) channel->size)
{
Y = data[i++];
Cb = data[i++];
j = Y + (Cb << 8) + (Cr << 16);
pixels[0]=RGBA_from_YUYV[j];
Y = data[i++];
Cr = data[i++];
j = Y + (Cb << 8) + (Cr << 16);
pixels[1]=RGBA_from_YUYV[j];
pixels+=2;
}
iterations++;
blc_command_loop_end();
gtk_image_set_from_surface(image, image_surface);
return G_SOURCE_CONTINUE;
}
// 4:2:2
gboolean update_yuv2_image(GtkImage *image, GdkFrameClock *, gpointer pointer_statusbar)
{
double sx, sy;
int x, y;
int i, j;
uchar *data = (uchar*) channel->data;
char text[NAME_MAX];
uint32_t *tmp_pixels;
int Y, U = 128, V = 128;
tmp_pixels = (uint32_t*)image_buffer;
i = 0;
while (i != (int) channel->size)
{
U = data[i++];
Y = data[i++];
j = Y + (U << 8) + (V << 16);
tmp_pixels[0]=RGBA_from_YUYV[j];
V = data[i++];
Y = data[i++];
j = Y + (U << 8) + (V << 16);
tmp_pixels[1]=RGBA_from_YUYV[j];
tmp_pixels+=2;
}
gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(image)), pointer_device, &x, &y, NULL);
cairo_surface_get_device_scale(image_surface, &sx, &sy);
i=x*sx;
j=y*sy;
if (i<width && j<height && i>=0 && j>=0)