kopia lustrzana https://gitlab.com/sane-project/frontends
preview: use GPixBuf and and lib function to do resize
Better to use stock functions to do image preview resizing.preview_fixes
rodzic
b330f79c18
commit
8b7d063442
292
src/preview.c
292
src/preview.c
|
@ -156,14 +156,24 @@ screen_size_get_dimensions (gint *width, gint *height)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
draw_rect(cairo_t *cr, double coord[4])
|
draw_selection (Preview *p, cairo_t *cr)
|
||||||
{
|
{
|
||||||
|
if (!p->selection.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double *coord = p->selection.coord;
|
||||||
double x, y, w, h;
|
double x, y, w, h;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that we account for a selection dragged in reverse
|
||||||
|
* from what we expect, e.g leftwards or upwards or both.
|
||||||
|
*
|
||||||
|
*/
|
||||||
x = coord[0];
|
x = coord[0];
|
||||||
y = coord[1];
|
y = coord[1];
|
||||||
w = coord[2] - x;
|
w = coord[2] - x;
|
||||||
h = coord[3] - y;
|
h = coord[3] - y;
|
||||||
|
|
||||||
if (w < 0)
|
if (w < 0)
|
||||||
{
|
{
|
||||||
x = coord[2];
|
x = coord[2];
|
||||||
|
@ -174,34 +184,32 @@ draw_rect(cairo_t *cr, double coord[4])
|
||||||
y = coord[3];
|
y = coord[3];
|
||||||
h = -h;
|
h = -h;
|
||||||
}
|
}
|
||||||
cairo_set_line_width(cr, 1.5);
|
|
||||||
|
/*
|
||||||
|
* Draw selection rectangle. One black dash, then another, filling in the
|
||||||
|
* black dash gaps with white. This means that regardless of the picture, the
|
||||||
|
* dash pattern is visible.
|
||||||
|
*
|
||||||
|
*/
|
||||||
const double dashes1[2] = { 4.0, 4.0 };
|
const double dashes1[2] = { 4.0, 4.0 };
|
||||||
|
const double dashes2[4] = { 0.0, 4.0, 4.0, 0.0 };
|
||||||
|
|
||||||
|
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||||
|
cairo_set_line_width (cr, 1.5);
|
||||||
|
|
||||||
|
// Black dashes.
|
||||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||||
cairo_set_dash (cr, dashes1, sizeof(dashes1) / sizeof(dashes1[0]), 0);
|
cairo_set_dash (cr, dashes1, sizeof(dashes1) / sizeof(dashes1[0]), 0);
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
|
||||||
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
|
|
||||||
cairo_rectangle (cr, x, y, w + 1, h + 1);
|
cairo_rectangle (cr, x, y, w + 1, h + 1);
|
||||||
cairo_stroke (cr);
|
cairo_stroke (cr);
|
||||||
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
|
|
||||||
const double dashes2[4] = {0.0, 4.0, 4.0, 0.0};
|
// White dashes.
|
||||||
cairo_set_dash (cr, dashes2, sizeof(dashes2) / sizeof(dashes2[0]), 0);
|
cairo_set_dash (cr, dashes2, sizeof(dashes2) / sizeof(dashes2[0]), 0);
|
||||||
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
|
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
|
||||||
cairo_rectangle (cr, x, y, w + 1, h + 1);
|
cairo_rectangle (cr, x, y, w + 1, h + 1);
|
||||||
cairo_stroke (cr);
|
cairo_stroke (cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
draw_selection (Preview * p, cairo_t *cr)
|
|
||||||
{
|
|
||||||
if (p->previous_selection.active)
|
|
||||||
draw_rect (cr, p->previous_selection.coord);
|
|
||||||
|
|
||||||
if (p->selection.active)
|
|
||||||
draw_rect (cr, p->selection.coord);
|
|
||||||
|
|
||||||
p->previous_selection = p->selection;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_selection (Preview * p)
|
update_selection (Preview * p)
|
||||||
{
|
{
|
||||||
|
@ -211,8 +219,6 @@ update_selection (Preview * p)
|
||||||
SANE_Word val;
|
SANE_Word val;
|
||||||
int i, optnum;
|
int i, optnum;
|
||||||
|
|
||||||
p->previous_selection = p->selection;
|
|
||||||
|
|
||||||
memcpy (dev_selection, p->surface, sizeof (dev_selection));
|
memcpy (dev_selection, p->surface, sizeof (dev_selection));
|
||||||
for (i = 0; i < 4; ++i)
|
for (i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
|
@ -288,62 +294,62 @@ get_image_scale (Preview * p, float *xscalep, float *yscalep)
|
||||||
static void
|
static void
|
||||||
paint_image (Preview * p)
|
paint_image (Preview * p)
|
||||||
{
|
{
|
||||||
float xscale, yscale, src_x, src_y;
|
// float xscale, yscale, src_x, src_y;
|
||||||
int dst_x, dst_y, height, x, y, src_offset;
|
// int dst_x, dst_y, height, x, y, src_offset;
|
||||||
gint gwidth, gheight;
|
// gint gwidth, gheight;
|
||||||
|
//
|
||||||
gwidth = p->preview_width;
|
// gwidth = p->preview_width;
|
||||||
gheight = p->preview_height;
|
// gheight = p->preview_height;
|
||||||
|
//
|
||||||
get_image_scale (p, &xscale, &yscale);
|
// get_image_scale (p, &xscale, &yscale);
|
||||||
|
//
|
||||||
if (p->preview_row == NULL)
|
// if (p->preview_row == NULL)
|
||||||
p->preview_row = malloc (3 * gwidth);
|
// p->preview_row = malloc (3 * gwidth);
|
||||||
else
|
// else
|
||||||
p->preview_row = realloc (p->preview_row, 3 * gwidth);
|
// p->preview_row = realloc (p->preview_row, 3 * gwidth);
|
||||||
memset (p->preview_row, 0xff, 3 * gwidth);
|
// memset (p->preview_row, 0xff, 3 * gwidth);
|
||||||
if (p->preview_data == NULL)
|
//// if (p->preview_data == NULL)
|
||||||
p->preview_data = malloc (3 * gwidth * gheight);
|
//// p->preview_data = malloc (3 * gwidth * gheight);
|
||||||
else
|
//// else
|
||||||
p->preview_data = realloc (p->preview_data, 3 * gwidth * gheight);
|
//// p->preview_data = realloc (p->preview_data, 3 * gwidth * gheight);
|
||||||
memset (p->preview_data, 0xff, 3 * gwidth * gheight);
|
//// memset (p->preview_data, 0xff, 3 * gwidth * gheight);
|
||||||
gtk_widget_queue_draw (p->window);
|
// gtk_widget_queue_draw (p->window);
|
||||||
|
//
|
||||||
/* don't draw last line unless it's complete: */
|
// /* don't draw last line unless it's complete: */
|
||||||
height = p->image_y;
|
// height = p->image_y;
|
||||||
if (p->image_x == 0 && height < p->image_height)
|
// if (p->image_x == 0 && height < p->image_height)
|
||||||
++height;
|
// ++height;
|
||||||
|
//
|
||||||
/* for now, use simple nearest-neighbor interpolation: */
|
// /* for now, use simple nearest-neighbor interpolation: */
|
||||||
src_offset = 0;
|
// src_offset = 0;
|
||||||
src_x = src_y = 0.0;
|
// src_x = src_y = 0.0;
|
||||||
for (dst_y = 0; dst_y < gheight; ++dst_y)
|
// for (dst_y = 0; dst_y < gheight; ++dst_y)
|
||||||
{
|
// {
|
||||||
y = (int) (src_y + 0.5);
|
// y = (int) (src_y + 0.5);
|
||||||
if (y >= height)
|
// if (y >= height)
|
||||||
break;
|
// break;
|
||||||
src_offset = y * 3 * p->image_width;
|
// src_offset = y * 3 * p->image_width;
|
||||||
|
//
|
||||||
if (p->image_data)
|
// if (p->image_data)
|
||||||
for (dst_x = 0; dst_x < gwidth; ++dst_x)
|
// for (dst_x = 0; dst_x < gwidth; ++dst_x)
|
||||||
{
|
// {
|
||||||
x = (int) (src_x + 0.5);
|
// x = (int) (src_x + 0.5);
|
||||||
if (x >= p->image_width)
|
// if (x >= p->image_width)
|
||||||
break;
|
// break;
|
||||||
|
//
|
||||||
p->preview_row[3 * dst_x + 0] =
|
// p->preview_row[3 * dst_x + 0] =
|
||||||
p->image_data[src_offset + 3 * x + 0];
|
// p->image_data[src_offset + 3 * x + 0];
|
||||||
p->preview_row[3 * dst_x + 1] =
|
// p->preview_row[3 * dst_x + 1] =
|
||||||
p->image_data[src_offset + 3 * x + 1];
|
// p->image_data[src_offset + 3 * x + 1];
|
||||||
p->preview_row[3 * dst_x + 2] =
|
// p->preview_row[3 * dst_x + 2] =
|
||||||
p->image_data[src_offset + 3 * x + 2];
|
// p->image_data[src_offset + 3 * x + 2];
|
||||||
src_x += xscale;
|
// src_x += xscale;
|
||||||
}
|
// }
|
||||||
memcpy(p->preview_data + (size_t) dst_y * (size_t) gwidth * 3, p->preview_row, (size_t) gwidth * 3);
|
// memcpy(p->preview_data + (size_t) dst_y * (size_t) gwidth * 3, p->preview_row, (size_t) gwidth * 3);
|
||||||
src_x = 0.0;
|
// src_x = 0.0;
|
||||||
src_y += yscale;
|
// src_y += yscale;
|
||||||
}
|
// }
|
||||||
gtk_widget_queue_draw (p->window);
|
// gtk_widget_queue_draw (p->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -376,8 +382,8 @@ display_image (Preview * p)
|
||||||
p->image_data = realloc (p->image_data,
|
p->image_data = realloc (p->image_data,
|
||||||
3 * p->image_width * p->image_height);
|
3 * p->image_width * p->image_height);
|
||||||
assert (p->image_data);
|
assert (p->image_data);
|
||||||
p->preview_data = realloc (p->preview_data,
|
// p->preview_data = realloc (p->preview_data,
|
||||||
3 * p->image_width * p->image_height);
|
// 3 * p->image_width * p->image_height);
|
||||||
}
|
}
|
||||||
display_partial_image (p);
|
display_partial_image (p);
|
||||||
scan_done (p);
|
scan_done (p);
|
||||||
|
@ -608,7 +614,7 @@ increment_image_y (Preview * p)
|
||||||
extra_size = 3 * 32 * p->image_width;
|
extra_size = 3 * 32 * p->image_width;
|
||||||
p->image_height += 32;
|
p->image_height += 32;
|
||||||
p->image_data = realloc (p->image_data, offset + extra_size);
|
p->image_data = realloc (p->image_data, offset + extra_size);
|
||||||
p->preview_data = realloc (p->preview_data, offset + extra_size);
|
// p->preview_data = realloc (p->preview_data, offset + extra_size);
|
||||||
if (!p->image_data)
|
if (!p->image_data)
|
||||||
{
|
{
|
||||||
snprintf (buf, sizeof (buf),
|
snprintf (buf, sizeof (buf),
|
||||||
|
@ -619,7 +625,10 @@ increment_image_y (Preview * p)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset (p->image_data + offset, 0xff, extra_size);
|
memset (p->image_data + offset, 0xff, extra_size);
|
||||||
memset (p->preview_data + offset, 0xff, extra_size);
|
// memset (p->preview_data + offset, 0xff, extra_size);
|
||||||
|
|
||||||
|
g_object_unref(p->image_pixbuf);
|
||||||
|
p->image_pixbuf = NULL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -949,12 +958,16 @@ scan_start (Preview * p)
|
||||||
gsg_set_sensitivity (p->dialog, FALSE);
|
gsg_set_sensitivity (p->dialog, FALSE);
|
||||||
// gtk_widget_set_sensitive (p->dialog->window->parent->parent->parent, FALSE);
|
// gtk_widget_set_sensitive (p->dialog->window->parent->parent->parent, FALSE);
|
||||||
|
|
||||||
if (p->preview_data == NULL)
|
// if (p->preview_data == NULL)
|
||||||
p->preview_data = malloc (p->image_width * p->image_height * 3);
|
// p->preview_data = malloc (p->image_width * p->image_height * 3);
|
||||||
else
|
// else
|
||||||
p->preview_data = realloc (p->preview_data, 3 * p->image_width * p->image_height);
|
// p->preview_data = realloc (p->preview_data, 3 * p->image_width * p->image_height);
|
||||||
/* clear old preview: */
|
/* clear old preview: */
|
||||||
memset (p->preview_data, 0xff, 3 * p->image_width * p->image_height);
|
// memset (p->preview_data, 0xff, 3 * p->image_width * p->image_height);
|
||||||
|
|
||||||
|
g_object_unref(p->image_pixbuf);
|
||||||
|
p->image_pixbuf = NULL;
|
||||||
|
|
||||||
gtk_widget_queue_draw (p->window);
|
gtk_widget_queue_draw (p->window);
|
||||||
|
|
||||||
if (p->input_tag >= 0)
|
if (p->input_tag >= 0)
|
||||||
|
@ -1040,6 +1053,12 @@ scan_start (Preview * p)
|
||||||
if (!p->image_data || p->params.pixels_per_line != p->image_width
|
if (!p->image_data || p->params.pixels_per_line != p->image_width
|
||||||
|| (p->params.lines >= 0 && p->params.lines != p->image_height))
|
|| (p->params.lines >= 0 && p->params.lines != p->image_height))
|
||||||
{
|
{
|
||||||
|
if (p->image_pixbuf)
|
||||||
|
{
|
||||||
|
g_object_unref(p->image_pixbuf);
|
||||||
|
p->image_pixbuf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* image size changed */
|
/* image size changed */
|
||||||
if (p->image_data)
|
if (p->image_data)
|
||||||
free (p->image_data);
|
free (p->image_data);
|
||||||
|
@ -1050,7 +1069,7 @@ scan_start (Preview * p)
|
||||||
p->image_height = 32; /* may have to adjust as we go... */
|
p->image_height = 32; /* may have to adjust as we go... */
|
||||||
|
|
||||||
p->image_data = malloc (p->image_width * p->image_height * 3);
|
p->image_data = malloc (p->image_width * p->image_height * 3);
|
||||||
p->preview_data = malloc (p->preview_width * p->image_height * 3);
|
// p->preview_data = malloc (p->preview_width * p->image_height * 3);
|
||||||
if (!p->image_data)
|
if (!p->image_data)
|
||||||
{
|
{
|
||||||
snprintf (buf, sizeof (buf),
|
snprintf (buf, sizeof (buf),
|
||||||
|
@ -1064,7 +1083,7 @@ scan_start (Preview * p)
|
||||||
|
|
||||||
if (p->selection.active)
|
if (p->selection.active)
|
||||||
{
|
{
|
||||||
p->previous_selection = p->selection;
|
// p->previous_selection = p->selection;
|
||||||
p->selection.active = FALSE;
|
p->selection.active = FALSE;
|
||||||
gtk_widget_queue_draw (p->window);
|
gtk_widget_queue_draw (p->window);
|
||||||
}
|
}
|
||||||
|
@ -1129,23 +1148,22 @@ restore_preview_image (Preview * p)
|
||||||
int width, height;
|
int width, height;
|
||||||
float psurface[4];
|
float psurface[4];
|
||||||
size_t nread;
|
size_t nread;
|
||||||
FILE *in;
|
FILE *in = NULL;
|
||||||
|
|
||||||
/* See whether there is a saved preview and load it if present: */
|
/* See whether there is a saved preview and load it if present: */
|
||||||
|
|
||||||
if (make_preview_image_path (p, sizeof (filename), filename) < 0)
|
if (make_preview_image_path (p, sizeof (filename), filename) < 0)
|
||||||
return;
|
goto finish;
|
||||||
|
|
||||||
in = fopen (filename, "r");
|
in = fopen (filename, "r");
|
||||||
if (!in)
|
if (!in)
|
||||||
return;
|
goto finish;
|
||||||
|
|
||||||
/* Be careful about consuming too many bytes after the final newline
|
/* Be careful about consuming too many bytes after the final newline
|
||||||
(e.g., consider an image whose first image byte is 13 (`\r'). */
|
(e.g., consider an image whose first image byte is 13 (`\r'). */
|
||||||
if (fscanf (in, "P6\n# surface: %g %g %g %g %u %u\n%d %d\n255%*[\n]",
|
if (fscanf (in, "P6\n# surface: %g %g %g %g %u %u\n%d %d\n255%*[\n]",
|
||||||
psurface + 0, psurface + 1, psurface + 2, psurface + 3,
|
psurface + 0, psurface + 1, psurface + 2, psurface + 3,
|
||||||
&psurface_type, &psurface_unit, &width, &height) != 8)
|
&psurface_type, &psurface_unit, &width, &height) != 8)
|
||||||
return;
|
goto finish;
|
||||||
|
|
||||||
if (GROSSLY_DIFFERENT (psurface[0], p->surface[0])
|
if (GROSSLY_DIFFERENT (psurface[0], p->surface[0])
|
||||||
|| GROSSLY_DIFFERENT (psurface[1], p->surface[1])
|
|| GROSSLY_DIFFERENT (psurface[1], p->surface[1])
|
||||||
|
@ -1153,12 +1171,12 @@ restore_preview_image (Preview * p)
|
||||||
|| GROSSLY_DIFFERENT (psurface[3], p->surface[3])
|
|| GROSSLY_DIFFERENT (psurface[3], p->surface[3])
|
||||||
|| psurface_type != p->surface_type || psurface_unit != p->surface_unit)
|
|| psurface_type != p->surface_type || psurface_unit != p->surface_unit)
|
||||||
/* ignore preview image that was acquired for/with a different surface */
|
/* ignore preview image that was acquired for/with a different surface */
|
||||||
return;
|
goto finish;
|
||||||
|
|
||||||
p->image_width = width;
|
p->image_width = width;
|
||||||
p->image_height = height;
|
p->image_height = height;
|
||||||
if ((width == 0) || (height == 0))
|
if ((width == 0) || (height == 0))
|
||||||
return;
|
goto finish;
|
||||||
|
|
||||||
int data_size = 3 * width * height;
|
int data_size = 3 * width * height;
|
||||||
|
|
||||||
|
@ -1166,25 +1184,21 @@ restore_preview_image (Preview * p)
|
||||||
if ((data_size / width) / height != 3)
|
if ((data_size / width) / height != 3)
|
||||||
{
|
{
|
||||||
// overflow occurred. Ignore the image. The dimensions are probably corrupted.
|
// overflow occurred. Ignore the image. The dimensions are probably corrupted.
|
||||||
return;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->image_data = malloc (data_size);
|
p->image_data = malloc (data_size);
|
||||||
if (!p->image_data)
|
if (!p->image_data)
|
||||||
return;
|
goto finish;
|
||||||
|
|
||||||
p->preview_data = malloc (data_size);
|
|
||||||
if (!p->preview_data)
|
|
||||||
{
|
|
||||||
free(p->image_data);
|
|
||||||
p->image_data = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nread = fread (p->image_data, 3, width * height, in);
|
nread = fread (p->image_data, 3, width * height, in);
|
||||||
|
|
||||||
p->image_y = nread / width;
|
p->image_y = nread / width;
|
||||||
p->image_x = nread % width;
|
p->image_x = nread % width;
|
||||||
|
|
||||||
|
finish:
|
||||||
|
if (in)
|
||||||
|
fclose(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is executed _after_ the gtkpreview's expose routine. */
|
/* This is executed _after_ the gtkpreview's expose routine. */
|
||||||
|
@ -1193,13 +1207,40 @@ expose_handler (GtkWidget * window, cairo_t *cr, gpointer data)
|
||||||
{
|
{
|
||||||
Preview *p = data;
|
Preview *p = data;
|
||||||
|
|
||||||
if (p->preview_data == NULL) return FALSE;
|
if (p->image_data == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(p->preview_data, GDK_COLORSPACE_RGB, FALSE, 8, p->preview_width,
|
if (p->image_pixbuf == NULL)
|
||||||
p->preview_height, p->preview_width * 3, NULL/*preview_pixbuf_data_destroy*/, NULL);
|
{
|
||||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
p->image_pixbuf = gdk_pixbuf_new_from_data (p->image_data,
|
||||||
|
GDK_COLORSPACE_RGB, FALSE, 8,
|
||||||
|
p->image_width,
|
||||||
|
p->image_height,
|
||||||
|
p->image_width * 3, NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
gint width = gtk_widget_get_allocated_width (window);
|
||||||
|
gint height = gtk_widget_get_allocated_height (window);
|
||||||
|
|
||||||
|
gint img_width = gdk_pixbuf_get_width (p->image_pixbuf);
|
||||||
|
gint img_height = gdk_pixbuf_get_height (p->image_pixbuf);
|
||||||
|
double scale = MIN((double )width / img_width, (double )height / img_height);
|
||||||
|
gint scaled_width = img_width * scale;
|
||||||
|
gint scaled_height = img_height * scale;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: we could store this scaled pixbuf in the Preview and only regenerate it
|
||||||
|
* when the scaled image dimensions change. [RL]
|
||||||
|
*/
|
||||||
|
GdkPixbuf *scaled = gdk_pixbuf_scale_simple (p->image_pixbuf, scaled_width,
|
||||||
|
scaled_height,
|
||||||
|
GDK_INTERP_BILINEAR);
|
||||||
|
|
||||||
|
gdk_cairo_set_source_pixbuf (cr, scaled, 0, 0);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
g_object_unref(pixbuf);
|
g_object_unref(scaled);
|
||||||
|
|
||||||
if (p->selection_drag == FALSE)
|
if (p->selection_drag == FALSE)
|
||||||
update_selection (p);
|
update_selection (p);
|
||||||
|
@ -1317,10 +1358,10 @@ preview_new (GSGDialog * dialog)
|
||||||
p->surface_unit = SANE_UNIT_MM;
|
p->surface_unit = SANE_UNIT_MM;
|
||||||
p->input_tag = -1;
|
p->input_tag = -1;
|
||||||
p->image_data = NULL;
|
p->image_data = NULL;
|
||||||
p->preview_data = NULL;
|
|
||||||
p->preview_row = NULL;
|
p->preview_row = NULL;
|
||||||
p->top = NULL;
|
p->top = NULL;
|
||||||
p->scanning = FALSE;
|
p->scanning = FALSE;
|
||||||
|
p->image_pixbuf = NULL;
|
||||||
|
|
||||||
if (first_time)
|
if (first_time)
|
||||||
{
|
{
|
||||||
|
@ -1470,9 +1511,11 @@ preview_update (Preview * p)
|
||||||
if (surface_changed && p->image_data)
|
if (surface_changed && p->image_data)
|
||||||
{
|
{
|
||||||
free (p->image_data);
|
free (p->image_data);
|
||||||
free (p->preview_data);
|
|
||||||
|
g_object_unref(p->image_pixbuf);
|
||||||
|
p->image_pixbuf = NULL;
|
||||||
|
|
||||||
p->image_data = 0;
|
p->image_data = 0;
|
||||||
p->preview_data = 0;
|
|
||||||
p->image_width = 0;
|
p->image_width = 0;
|
||||||
p->image_height = 0;
|
p->image_height = 0;
|
||||||
}
|
}
|
||||||
|
@ -1630,6 +1673,11 @@ preview_destroy (Preview * p)
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
FILE *out;
|
FILE *out;
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (p->scanning)
|
if (p->scanning)
|
||||||
scan_done (p); /* don't save partial window */
|
scan_done (p); /* don't save partial window */
|
||||||
else if (preferences.preserve_preview && p->image_data
|
else if (preferences.preserve_preview && p->image_data
|
||||||
|
@ -1648,15 +1696,29 @@ preview_destroy (Preview * p)
|
||||||
fclose (out);
|
fclose (out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->image_data)
|
if (p->image_data)
|
||||||
|
{
|
||||||
free (p->image_data);
|
free (p->image_data);
|
||||||
p->image_data = NULL;
|
p->image_data = NULL;
|
||||||
if (p->preview_data)
|
}
|
||||||
free (p->preview_data);
|
|
||||||
p->preview_data = NULL;
|
// if (p->preview_data)
|
||||||
|
// free (p->preview_data);
|
||||||
|
// p->preview_data = NULL;
|
||||||
|
|
||||||
|
if (p->image_pixbuf)
|
||||||
|
{
|
||||||
|
g_object_unref(p->image_pixbuf);
|
||||||
|
p->image_pixbuf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (p->preview_row)
|
if (p->preview_row)
|
||||||
|
{
|
||||||
free (p->preview_row);
|
free (p->preview_row);
|
||||||
p->preview_row = NULL;
|
p->preview_row = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (p->top)
|
if (p->top)
|
||||||
gtk_widget_destroy (p->top);
|
gtk_widget_destroy (p->top);
|
||||||
free (p);
|
free (p);
|
||||||
|
|
|
@ -62,7 +62,6 @@ typedef struct
|
||||||
int image_width;
|
int image_width;
|
||||||
int image_height;
|
int image_height;
|
||||||
u_char *image_data; /* 3 * image_width * image_height bytes */
|
u_char *image_data; /* 3 * image_width * image_height bytes */
|
||||||
u_char *preview_data; /* 3 * image_width * image_height bytes */
|
|
||||||
|
|
||||||
int selection_drag;
|
int selection_drag;
|
||||||
struct
|
struct
|
||||||
|
@ -70,7 +69,7 @@ typedef struct
|
||||||
int active;
|
int active;
|
||||||
double coord[4];
|
double coord[4];
|
||||||
}
|
}
|
||||||
selection, previous_selection;
|
selection; // coords of selection box in the preview window
|
||||||
|
|
||||||
GtkWidget *top; /* top-level widget */
|
GtkWidget *top; /* top-level widget */
|
||||||
GtkWidget *hruler;
|
GtkWidget *hruler;
|
||||||
|
@ -80,8 +79,7 @@ typedef struct
|
||||||
GtkWidget *cancel; /* the cancel button */
|
GtkWidget *cancel; /* the cancel button */
|
||||||
GtkWidget *preview; /* the preview button */
|
GtkWidget *preview; /* the preview button */
|
||||||
|
|
||||||
cairo_surface_t *surface_cairo;
|
GdkPixbuf *image_pixbuf;
|
||||||
gboolean drawable;
|
|
||||||
}
|
}
|
||||||
Preview;
|
Preview;
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue