Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
blaar
gtk
Commits
11324484
Commit
11324484
authored
May 26, 2021
by
Arnaud Blanchard
Browse files
Modern version of blc
parent
539bc0b8
Changes
8
Hide whitespace changes
Inline
Side-by-side
c_gtk_image/CMakeLists.txt
View file @
11324484
...
...
@@ -6,7 +6,6 @@ project(c_gtk_image)
#This is to be able to debug and recompile automatically the libs (shared_blc). It is slower, you can remove this line and use : ${BLAR_BUILD_DIR}/lib/libblc.dylib instead of shared_blc
find_package
(
blc REQUIRED
)
find_package
(
PkgConfig REQUIRED
)
pkg_check_modules
(
GTK3 REQUIRED gtk+-3.0
)
find_package
(
JPEG REQUIRED
)
...
...
c_gtk_image/network_display.cpp
0 → 100644
View file @
11324484
#include
"blc.h"
#include
"network_display.h"
#include
<string>
#include
"Display.hpp"
using
namespace
std
;
Tcp4ClientDisplay
::
Tcp4ClientDisplay
(
string
const
&
address
,
string
const
&
port
)
:
blc_array_tcp4_client
(
address
,
port
){
}
gboolean
refresh_screen_callback
(
GtkWidget
*
widget
,
GdkFrameClock
*
frame_clock
,
Tcp4ClientDisplay
*
client
){
char
text
[
64
];
int
x
,
y
,
i
,
j
;
double
x_scale
,
y_scale
;
if
(
blc_command_loop_start
()){
client
->
recv_data
();
client
->
display
->
update
();
return
G_SOURCE_CONTINUE
;
}
else
exit
(
EXIT_SUCCESS
);
}
c_gtk_image/network_display.h
0 → 100644
View file @
11324484
#ifndef NETWORK_DISPLAY_H
#define NETWORK_DISPLAY_H
#include
<gtk/gtk.h>
#include
<blc_array_network.h>
#include
"Display.hpp"
class
Tcp4ClientDisplay
:
public
blc_array_tcp4_client
{
public:
Tcp4ClientDisplay
(
std
::
string
const
&
address
,
std
::
string
const
&
port
);
std
::
unique_ptr
<
Display
>
display
;
};
#endif
include/Image.hpp
View file @
11324484
...
...
@@ -27,7 +27,6 @@ public:
/** set pointer position (i, j) in the window. return false if the pointer is not in the window. */
bool
get_pointer_position
(
int
&
i
,
int
&
j
);
/** Display the new image with the content array.*/
virtual
void
update
()
=
0
;
...
...
o_gtk_image/common.h
0 → 100644
View file @
11324484
#ifndef COMMON_H
#define COMMON_H
#include
<gtk/gtk.h>
#include
<blc.h>
#include
<image_display.h>
extern
GtkWidget
*
legend
;
extern
u_int32_t
false_colors
[
256
];
extern
uint32_t
gray_colors
[
256
];
extern
uint32_t
u_colors
[
256
];
extern
uint32_t
v_colors
[
256
];
extern
uint32_t
r_colors
[
256
];
extern
uint32_t
g_colors
[
256
];
extern
uint32_t
b_colors
[
256
];
extern
uint32_t
*
color_map
;
extern
GtkWidget
*
window
,
*
paned
;
extern
GdkDevice
*
pointer_device
;
extern
blc_array
mouse_array
;
extern
char
const
*
fullscreen_option
;
void
histogram_cb
(
GtkToolButton
*
toolbutton
,
gpointer
pointer_statusbar
);
GtkWidget
*
create_image_display
(
blc_array
*
array
);
#endif
o_gtk_image/histogram.cpp
0 → 100644
View file @
11324484
#include
"common.h"
#include
<fcntl.h>
// O_RDONLY ...
#include
<stdio.h>
#include
<gtk/gtk.h>
#include
<string.h>
#include
<stdint.h>
//uint32_t
#include
<jpeglib.h>
#include
<sys/mman.h>
#include
<errno.h>
//errno
#include
"blc_image.h"
#include
"blc_realtime.h"
#include
"blc_program.h"
//blc_status
//cairo_surface_t *legend_surface;
guint
histogram_tick_id
;
uint32_t
*
histogram_data
=
NULL
;
cairo_surface_t
*
histogram_surface
;
static
void
draw_histogram
(
uint32_t
*
drawing
,
int
height
,
int
histogram
[
256
],
uint32_t
color_map
[
256
],
int
max
){
int
i
,
j
,
val
;
FOR_INV
(
i
,
256
)
{
val
=
height
-
histogram
[
i
]
*
(
height
-
1
)
/
max
;
for
(
j
=
height
;
j
!=
val
;
j
--
)
drawing
[
j
*
256
+
i
]
=
color_map
[
i
];
drawing
[
val
*
256
+
i
]
=
255
<<
24
;
FOR_INV
(
j
,
val
)
drawing
[
j
*
256
+
i
]
=
0
;
}
}
static
gboolean
update_histogram_cb
(
GtkImage
*
image
,
GdkFrameClock
*
,
gpointer
pointer_statusbar
){
int
i
,
j
,
x
,
y
;
double
sx
,
sy
;
int
histogram
[
256
]
=
{
0
},
histogram1
[
256
]
=
{
0
},
histogram2
[
256
]
=
{
0
},
hist_max
=
0
,
max1
=
0
,
max2
=
0
;
char
text
[
64
];
struct
timeval
timer
;
CLEAR
(
timer
);
gdk_window_get_device_position
(
gtk_widget_get_window
(
GTK_WIDGET
(
image
)),
pointer_device
,
&
x
,
&
y
,
NULL
);
cairo_surface_get_device_scale
(
histogram_surface
,
&
sx
,
&
sy
);
x
*=
sx
;
y
*=
sy
;
switch
(
array
->
format
){
case
'
Y800
'
:
switch
(
array
->
type
){
case
'
UIN8
'
:
FOR
(
i
,
array
->
size
)
histogram
[
array
->
uchars
[
i
]]
++
;
FOR
(
i
,
256
)
hist_max
=
MAX
(
histogram
[
i
],
hist_max
);
FOR
(
i
,
256
)
{
FOR_INV
(
j
,
histogram
[
i
]
*
255
/
hist_max
)
histogram_data
[(
255
-
j
)
*
256
+
i
]
=
color_map
[
i
];
histogram_data
[(
255
-
histogram
[
i
]
*
255
/
hist_max
)
*
256
+
i
]
=
255
<<
24
;
FOR_INV
(
j
,
255
-
histogram
[
i
]
*
255
/
hist_max
)
histogram_data
[
j
*
256
+
i
]
=
0
;
}
if
(
y
>=
0
&&
y
<
256
&&
x
>=
0
&&
x
<
256
)
{
SPRINTF
(
text
,
"Y[%d]=%f.2%%"
,
x
,
histogram
[
x
]
*
100
/
(
float
)
array
->
size
);
gtk_statusbar_push
(
GTK_STATUSBAR
(
pointer_statusbar
),
0
,
text
);
}
break
;
case
'
FL32
'
:
FOR
(
i
,
array
->
total_length
)
histogram
[(
int
)
CLIP_UCHAR
(((
array
->
floats
[
i
]
-
min_val
)
/
(
max_val
-
min_val
)
*
256
+
0.5
))]
++
;
FOR
(
i
,
256
)
hist_max
=
MAX
(
histogram
[
i
],
hist_max
);
FOR
(
i
,
256
)
{
FOR_INV
(
j
,
histogram
[
i
]
*
255
/
hist_max
)
histogram_data
[(
255
-
j
)
*
256
+
i
]
=
color_map
[
i
];
histogram_data
[(
255
-
histogram
[
i
]
*
255
/
hist_max
)
*
256
+
i
]
=
255
<<
24
;
FOR_INV
(
j
,
255
-
histogram
[
i
]
*
255
/
hist_max
)
histogram_data
[
j
*
256
+
i
]
=
0
;
}
if
(
y
>=
0
&&
y
<
256
&&
x
>=
0
&&
x
<
256
)
{
SPRINTF
(
text
,
"Y[%f]=%f.2%%"
,
x
*
(
max_val
-
min_val
-
0.5
)
/
256
+
min_val
,
histogram
[
x
]
*
100
/
(
float
)
array
->
total_length
);
gtk_statusbar_push
(
GTK_STATUSBAR
(
pointer_statusbar
),
0
,
text
);
}
break
;
default:
EXIT_ON_ARRAY_ERROR
(
array
,
"Type not managed for format 'Y800'. Only 'UIN8' is"
);
}
break
;
case
'
RGB3
'
:
FOR_INV
(
i
,
array
->
size
/
3
){
histogram
[
array
->
uchars
[
i
*
3
]]
++
;
histogram1
[
array
->
uchars
[
i
*
3
+
1
]]
++
;
histogram2
[
array
->
uchars
[
i
*
3
+
2
]]
++
;
}
FOR_INV
(
i
,
256
)
{
hist_max
=
MAX
(
histogram
[
i
],
hist_max
);
max1
=
MAX
(
histogram1
[
i
],
max1
);
max2
=
MAX
(
histogram2
[
i
],
max2
);
}
draw_histogram
(
histogram_data
,
85
,
histogram
,
r_colors
,
hist_max
);
draw_histogram
(
histogram_data
+
256
*
85
,
85
,
histogram1
,
g_colors
,
max1
);
draw_histogram
(
histogram_data
+
256
*
170
,
85
,
histogram2
,
b_colors
,
max2
);
if
(
y
>=
0
&&
y
<
256
&&
x
>=
0
&&
x
<
256
)
{
if
(
y
<
85
)
SPRINTF
(
text
,
"R[%d]=%f.2%%"
,
x
,
histogram
[
x
]
*
100
*
2
/
(
float
)
array
->
size
);
else
if
(
y
<
170
)
SPRINTF
(
text
,
"G[%d]=%.2f%%"
,
x
,
histogram1
[
x
]
*
100
*
4
/
(
float
)
array
->
size
);
else
SPRINTF
(
text
,
"B[%d]=%.2f%%"
,
x
,
histogram2
[
x
]
*
100
*
4
/
(
float
)
array
->
size
);
gtk_statusbar_push
(
GTK_STATUSBAR
(
pointer_statusbar
),
0
,
text
);
}
break
;
case
'
YUYV
'
:
for
(
i
=
array
->
size
-
2
;
i
!=-
1
;
i
-=
2
)
histogram
[
array
->
uchars
[
i
]]
++
;
for
(
i
=
array
->
size
-
1
;
i
!=-
2
;
i
-=
4
)
histogram1
[
array
->
uchars
[
i
]]
++
;
for
(
i
=
array
->
size
-
3
;
i
!=-
4
;
i
-=
4
)
histogram2
[
array
->
uchars
[
i
]]
++
;
FOR_INV
(
i
,
256
)
{
hist_max
=
MAX
(
histogram
[
i
],
hist_max
);
max1
=
MAX
(
histogram1
[
i
],
max1
);
max2
=
MAX
(
histogram2
[
i
],
max2
);
}
draw_histogram
(
histogram_data
,
127
,
histogram
,
gray_colors
,
hist_max
);
draw_histogram
(
histogram_data
+
256
*
128
,
63
,
histogram1
,
u_colors
,
max1
);
draw_histogram
(
histogram_data
+
256
*
192
,
63
,
histogram2
,
v_colors
,
max2
);
if
(
y
>=
0
&&
y
<
256
&&
x
>=
0
&&
x
<
256
)
{
if
(
y
<
128
)
SPRINTF
(
text
,
"Y[%d]=%f.2%%"
,
x
,
histogram
[
x
]
*
100
*
2
/
(
float
)
array
->
size
);
else
if
(
y
<
192
)
SPRINTF
(
text
,
"U[%d]=%.2f%%"
,
x
,
histogram1
[
x
]
*
100
*
4
/
(
float
)
array
->
size
);
else
SPRINTF
(
text
,
"V[%d]=%.2f%%"
,
x
,
histogram2
[
x
]
*
100
*
4
/
(
float
)
array
->
size
);
gtk_statusbar_push
(
GTK_STATUSBAR
(
pointer_statusbar
),
0
,
text
);
}
break
;
case
'
yuv2
'
:
for
(
i
=
array
->
size
-
1
;
i
!=-
1
;
i
-=
2
)
histogram
[
array
->
uchars
[
i
]]
++
;
for
(
i
=
array
->
size
-
2
;
i
!=-
2
;
i
-=
4
)
histogram1
[
array
->
uchars
[
i
]]
++
;
for
(
i
=
array
->
size
-
4
;
i
!=-
4
;
i
-=
4
)
histogram2
[
array
->
uchars
[
i
]]
++
;
FOR_INV
(
i
,
256
)
{
hist_max
=
MAX
(
histogram
[
i
],
hist_max
);
max1
=
MAX
(
histogram1
[
i
],
max1
);
max2
=
MAX
(
histogram2
[
i
],
max2
);
}
draw_histogram
(
histogram_data
,
127
,
histogram
,
gray_colors
,
hist_max
);
draw_histogram
(
histogram_data
+
256
*
128
,
63
,
histogram1
,
u_colors
,
max1
);
draw_histogram
(
histogram_data
+
256
*
192
,
63
,
histogram2
,
v_colors
,
max2
);
if
(
y
>=
0
&&
y
<
256
&&
x
>=
0
&&
x
<
256
)
{
if
(
y
<
128
)
SPRINTF
(
text
,
"Y[%d]=%f.2%%"
,
x
,
histogram
[
x
]
*
100
*
2
/
(
float
)
array
->
size
);
else
if
(
y
<
192
)
SPRINTF
(
text
,
"U[%d]=%.2f%%"
,
x
,
histogram1
[
x
]
*
100
*
4
/
(
float
)
array
->
size
);
else
SPRINTF
(
text
,
"V[%d]=%.2f%%"
,
x
,
histogram2
[
x
]
*
100
*
4
/
(
float
)
array
->
size
);
gtk_statusbar_push
(
GTK_STATUSBAR
(
pointer_statusbar
),
0
,
text
);
}
break
;
default:
gtk_statusbar_push
(
GTK_STATUSBAR
(
pointer_statusbar
),
0
,
"No histogram for this format. Only Y800,RGB3 or yuv2."
);
}
gtk_image_set_from_surface
(
image
,
histogram_surface
);
return
G_SOURCE_CONTINUE
;
}
void
histogram_cb
(
GtkToolButton
*
toolbutton
,
gpointer
pointer_statusbar
)
{
char
text
[
NAME_MAX
];
GtkWidget
*
legend_box
,
*
label
;
if
(
gtk_toggle_tool_button_get_active
(
GTK_TOGGLE_TOOL_BUTTON
(
toolbutton
)))
{
histogram_data
=
MANY_ALLOCATIONS
(
256
*
256
,
uint32_t
);
histogram_surface
=
cairo_image_surface_create_for_data
((
uchar
*
)
histogram_data
,
CAIRO_FORMAT_ARGB32
,
256
,
256
,
256
*
4
);
histogram_image
=
gtk_image_new_from_surface
(
histogram_surface
);
histogram_scrolled_window
=
gtk_scrolled_window_new
(
NULL
,
NULL
);
histogram
=
gtk_box_new
(
GTK_ORIENTATION_VERTICAL
,
1
);
legend_box
=
gtk_box_new
(
GTK_ORIENTATION_HORIZONTAL
,
1
);
gtk_container_add
(
GTK_CONTAINER
(
histogram_scrolled_window
),
histogram_image
);
gtk_container_add
(
GTK_CONTAINER
(
histogram
),
histogram_scrolled_window
);
gtk_container_add
(
GTK_CONTAINER
(
histogram
),
legend_box
);
SPRINTF
(
text
,
"%f"
,
min_val
);
label
=
gtk_label_new
(
text
);
gtk_box_pack_start
(
GTK_BOX
(
legend_box
),
label
,
FALSE
,
FALSE
,
0
);
SPRINTF
(
text
,
"%f"
,
max_val
);
label
=
gtk_label_new
(
text
);
gtk_box_pack_end
(
GTK_BOX
(
legend_box
),
label
,
FALSE
,
FALSE
,
0
);
if
(
legend
){
gtk_container_remove
(
GTK_CONTAINER
(
paned
),
legend
);
legend
=
NULL
;
}
gtk_paned_add2
(
GTK_PANED
(
paned
),
histogram
);
gtk_widget_set_vexpand
(
histogram_image
,
TRUE
);
gtk_paned_set_position
(
GTK_PANED
(
paned
),
gtk_widget_get_allocated_height
(
paned
)
-
256
);
gtk_widget_show_all
(
paned
);
g_signal_connect
(
G_OBJECT
(
histogram_scrolled_window
),
"size-allocate"
,
G_CALLBACK
(
histogram_resize_cb
),
NULL
);
histogram_tick_id
=
gtk_widget_add_tick_callback
(
GTK_WIDGET
(
histogram_image
),
(
GtkTickCallback
)
update_histogram_cb
,
pointer_statusbar
,
NULL
);
}
else
{
gtk_widget_remove_tick_callback
(
GTK_WIDGET
(
histogram_image
),
histogram_tick_id
);
gtk_container_remove
(
GTK_CONTAINER
(
paned
),
histogram
);
FREE
(
histogram_data
);
// gtk_widget_destroy(histogram);
histogram
=
NULL
;
}
}
o_gtk_image/image_display.cpp
0 → 100644
View file @
11324484
#include
"common.h"
#include
<fcntl.h>
// O_RDONLY ...
#include
<stdio.h>
#include
<gtk/gtk.h>
#include
<string.h>
#include
<stdint.h>
//uint32_t
#include
<jpeglib.h>
#include
<sys/mman.h>
#include
<errno.h>
//errno
#include
"blc_image.h"
#include
"blc_realtime.h"
#include
"blc_program.h"
//blc_status
uint32_t
false_colors
[
256
];
uint32_t
gray_colors
[
256
];
uint32_t
u_colors
[
256
];
uint32_t
v_colors
[
256
];
uint32_t
r_colors
[
256
];
uint32_t
g_colors
[
256
];
uint32_t
b_colors
[
256
];
uint32_t
*
color_map
;
int
iterations
=
0
;
int
colors_initilized
=
0
;
int
mouse_image_x
,
mouse_image_y
;
cairo_surface_t
*
legend_surface
,
*
image_surface
;
gulong
pointer_value_handler
;
GtkWidget
*
paned
;
static
uint32_t
*
RGBA_from_YUYV
=
NULL
;
static
GtkWidget
*
vbox
,
*
scrolled_window
,
*
event_box
,
*
toolbar
,
*
general_statusbar
;
static
GtkWidget
*
zoom_button
,
*
false_colors_button
,
*
histogram_button
;
GtkWidget
*
image
;
static
uchar
*
image_buffer
;
static
pthread_t
init_table_thread
;
double
zoom_in_factor
=
2
,
zoom_out_factor
=
0.5
;
static
int
width
=
0
,
height
=
0
;
blc_array
*
array
=
NULL
;
static
int
g_source_continue
=
G_SOURCE_CONTINUE
;
#define SWAP_RGBA_TO_CAIRO_ARGB32(x) ((((x) & 0x000000FF) << 16) | (((x) & 0x00FF0000) >> 16) | ((x) & 0xFF00FF00) )
void
*
create_RGBA_from_YUYV
()
{
int
Y
,
Cb
,
Cr
;
int
i
,
j
;
float
G_tmp
;
static
uchar
R
[
256
],
B
;
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
;
}
}
}
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
();
}
/** 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
)
{
float
gain
;
int
i
,
x
,
y
,
j
;
double
sx
,
sy
;
uint32_t
*
values
;
char
text
[
64
];
gain
=
1
/
(
max_val
-
min_val
);
if
(
blc_command_loop_start
()){
values
=
(
uint32_t
*
)
image_buffer
;
if
(
array
->
type
==
'
UIN8
'
)
FOR
(
i
,
array
->
size
)
values
[
i
]
=
color_map
[
array
->
uchars
[
i
]];
else
if
(
array
->
type
==
'
FL32
'
)
FOR
(
i
,
array
->
total_length
)
values
[
i
]
=
color_map
[
CLIP_UCHAR
((
array
->
floats
[
i
]
-
min_val
)
*
256
*
gain
-
0.5
f
)];
else
EXIT_ON_ARRAY_ERROR
(
array
,
"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
(
array
->
type
==
'
UIN8
'
)
SPRINTF
(
text
,
"%4d,%4d: Y:%3d"
,
i
,
j
,
array
->
uchars
[
i
+
j
*
width
]);
else
if
(
array
->
type
==
'
FL32
'
)
SPRINTF
(
text
,
"%4d,%4d: Y:%.3f"
,
i
,
j
,
array
->
floats
[
i
+
j
*
width
]);
gtk_statusbar_push
(
GTK_STATUSBAR
(
pointer_statusbar
),
0
,
text
);
}
iterations
++
;
blc_command_loop_end
();
}
else
exit
(
EXIT_SUCCESS
);
return
G_SOURCE_CONTINUE
;
}
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
;
if
(
blc_command_loop_start
()){
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
!=
array
->
size
){
image_buffer
[
j
++
]
=
array
->
uchars
[
i
+
2
];
image_buffer
[
j
++
]
=
array
->
uchars
[
i
+
1
];
image_buffer
[
j
++
]
=
array
->
uchars
[
i
];
j
++
;
i
+=
3
;
}
i
=
x
*
sx
;
j
=
y
*
sy
;
if
(
i
<
width
&&
j
<
height
&&
i
>=
0
&&
j
>=
0
){
if
(
mouse_array
.
dims
!=
nullptr
)
{
mouse_array
.
uints32
[
0
]
=
i
;
mouse_array
.
uints32
[
1
]
=
j
;
gdk_device_get_state
(
pointer_device
,
gtk_widget_get_window
(
GTK_WIDGET
(
image
)),
NULL
,
(
GdkModifierType
*
)(
&
mouse_array
.
uints32
[
2
]));
}
R
=
array
->
uchars
[
i
*
4
+
j
*
width
*
3
];
G
=
array
->
uchars
[
i
*
4
+
j
*
width
*
3
+
1
];
B
=
array
->
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
++
;
blc_command_loop_end
();
}
else
exit
(
EXIT_SUCCESS
);
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
;
if
(
blc_command_loop_start
()
==
0
)
exit
(
0
);
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
,
array
->
size
/
4
)
((
uint32_t
*
)
image_buffer
)[
i
]
=
SWAP_RGBA_TO_CAIRO_ARGB32
(
array
->
uints32
[
i
]);
i
=
x
*
sx
;
j
=
y
*
sy
;
if
(
i
<
width
&&
j
<
height
&&
i
>=
0
&&
j
>=
0
){
if
(
mouse_array
.
dims
!=
nullptr
){
mouse_array
.
uints32
[
0
]
=
i
;
mouse_array
.
uints32
[
1
]
=
j
;
gdk_device_get_state
(
pointer_device
,
gtk_widget_get_window
(
GTK_WIDGET
(
image
)),
NULL
,
(
GdkModifierType
*
)(
&
mouse_array
.
uints32
[
2
]));
}
R
=
array
->
uchars
[
i
*
4
+
j
*
width
*
4
];
G
=
array
->
uchars
[
i
*
4
+
j
*
width
*
4
+
1
];
B
=
array
->
uchars
[
i
*
4
+
j
*
width
*
4
+
2
];
A
=
array
->
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
);
blc_command_loop_end
();
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
++
;
}
gboolean
update_JPEG_image
(
GtkImage
*
image
,
GdkFrameClock
*
frame_clock
,
blc_array
*
array
)
{
JSAMPROW
row_pt
[
1
];
GdkPixbuf
*
pixbuf
;
int
row_stride
;
uchar
*
pixels
;
struct
jpeg_decompress_struct
cinfo
;
struct
jpeg_error_mgr
jerr
;
(
void
)
frame_clock
;
if
(
blc_command_loop_start
()
==
0
)
exit
(
0
);
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
*
)
array
->
data
,
array
->
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
;