Commit 33e963e7 authored by Owen Taylor's avatar Owen Taylor Committed by Owen Taylor
Browse files

Directory full of pixel data scaling code that will eventually migrate

2000-01-05  Owen Taylor  <otaylor@redhat.com>

	* gdk-pixbuf/pixops/: Directory full of pixel data scaling
	code that will eventually migrate into libart.

	* configure.in acconfig.h: Add checks for MMX compiler support

	* gdk-pixbuf/gdk-pixbuf.h gdk-pixbuf/gdk-pixbuf-scale.c:
	Nice wrapper routines for the code in pixops that operate
	on pixbufs instead of raw data.

	* gdk-pixbuf/testpixbuf-scale: Test program for scaling
	routines.
parent 2bb20aee
#include <gtk/gtk.h>
#include "gdk-pixbuf.h"
#include <stdio.h>
ArtFilterLevel filter_level = ART_FILTER_BILINEAR;
int overall_alpha = 255;
GdkPixbuf *pixbuf;
GtkWidget *darea;
void
set_filter_level (GtkWidget *widget, gpointer data)
{
filter_level = GPOINTER_TO_UINT (data);
gtk_widget_queue_draw (darea);
}
void
overall_changed_cb (GtkAdjustment *adjustment, gpointer data)
{
if (adjustment->value != overall_alpha)
{
overall_alpha = adjustment->value;
gtk_widget_queue_draw (darea);
}
}
gboolean
expose_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
GdkPixbuf *dest;
dest = gdk_pixbuf_new (ART_PIX_RGB, FALSE, 8, event->area.width, event->area.height);
if (pixbuf->art_pixbuf->has_alpha || overall_alpha != 255)
gdk_pixbuf_composite_color (pixbuf, dest,
0, 0, event->area.width, event->area.height,
-event->area.x, -event->area.y,
(double) widget->allocation.width / pixbuf->art_pixbuf->width,
(double) widget->allocation.height / pixbuf->art_pixbuf->height,
filter_level, overall_alpha,
event->area.x, event->area.y, 16, 0xaaaaaa, 0x555555);
else
gdk_pixbuf_scale (pixbuf, dest,
0, 0, event->area.width, event->area.height,
-event->area.x, -event->area.y,
(double) widget->allocation.width / pixbuf->art_pixbuf->width,
(double) widget->allocation.height / pixbuf->art_pixbuf->height,
filter_level);
gdk_pixbuf_render_to_drawable (dest, widget->window, widget->style->fg_gc[GTK_STATE_NORMAL],
0, 0, event->area.x, event->area.y,
event->area.width, event->area.height,
GDK_RGB_DITHER_NORMAL, event->area.x, event->area.y);
gdk_pixbuf_unref (dest);
return TRUE;
}
int
main(int argc, char **argv)
{
GtkWidget *window, *vbox;
GtkWidget *menuitem, *optionmenu, *menu;
GtkWidget *alignment;
GtkWidget *hbox, *label, *hscale;
GtkAdjustment *adjustment;
GtkRequisition scratch_requisition;
gtk_init (&argc, &argv);
gdk_rgb_init ();
if (argc != 2) {
fprintf (stderr, "Usage: testpixbuf-scale FILE\n");
exit (1);
}
pixbuf = gdk_pixbuf_new_from_file (argv[1]);
if (!pixbuf) {
fprintf (stderr, "Cannot load %s\n", argv[1]);
exit(1);
}
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
menu = gtk_menu_new ();
menuitem = gtk_menu_item_new_with_label ("NEAREST");
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
GTK_SIGNAL_FUNC (set_filter_level),
GUINT_TO_POINTER (ART_FILTER_NEAREST));
gtk_widget_show (menuitem);
gtk_container_add (GTK_CONTAINER (menu), menuitem);
menuitem = gtk_menu_item_new_with_label ("BILINEAR");
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
GTK_SIGNAL_FUNC (set_filter_level),
GUINT_TO_POINTER (ART_FILTER_BILINEAR));
gtk_widget_show (menuitem);
gtk_container_add (GTK_CONTAINER (menu), menuitem);
menuitem = gtk_menu_item_new_with_label ("TILES");
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
GTK_SIGNAL_FUNC (set_filter_level),
GUINT_TO_POINTER (ART_FILTER_TILES));
gtk_container_add (GTK_CONTAINER (menu), menuitem);
menuitem = gtk_menu_item_new_with_label ("HYPER");
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
GTK_SIGNAL_FUNC (set_filter_level),
GUINT_TO_POINTER (ART_FILTER_HYPER));
gtk_container_add (GTK_CONTAINER (menu), menuitem);
optionmenu = gtk_option_menu_new ();
gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), 1);
alignment = gtk_alignment_new (0.0, 0.0, 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new ("Overall Alpha:");
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (overall_alpha, 0, 255, 1, 10, 0));
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
GTK_SIGNAL_FUNC (overall_changed_cb), NULL);
hscale = gtk_hscale_new (adjustment);
gtk_scale_set_digits (GTK_SCALE (hscale), 0);
gtk_box_pack_start (GTK_BOX (hbox), hscale, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (alignment), optionmenu);
gtk_widget_show_all (vbox);
/* Compute the size without the drawing area, so we know how big to make the default size */
gtk_widget_size_request (vbox, &scratch_requisition);
darea = gtk_drawing_area_new ();
gtk_box_pack_start (GTK_BOX (vbox), darea, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (darea), "expose_event",
GTK_SIGNAL_FUNC (expose_cb), NULL);
gtk_window_set_default_size (GTK_WINDOW (window),
pixbuf->art_pixbuf->width,
scratch_requisition.height + pixbuf->art_pixbuf->height);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
......@@ -7,4 +7,5 @@ Makefile
*.lo
testpixbuf
testpixbuf-drawable
testpixbuf-scale
testanimation
2000-01-05 Owen Taylor <otaylor@redhat.com>
* gdk-pixbuf/pixops/: Directory full of pixel data scaling
code that will eventually migrate into libart.
* configure.in acconfig.h: Add checks for MMX compiler support
* gdk-pixbuf/gdk-pixbuf.h gdk-pixbuf/gdk-pixbuf-scale.c:
Nice wrapper routines for the code in pixops that operate
on pixbufs instead of raw data.
* gdk-pixbuf/testpixbuf-scale: Test program for scaling
routines.
2000-01-05 Jonathan Blandford <jrb@redhat.com>
* doc/tmpl/animation.sgml: Documentation changes.
......
SUBDIRS = pixops
lib_LTLIBRARIES = \
libgdk_pixbuf.la
......@@ -38,7 +40,7 @@ libexec_LTLIBRARIES = \
$(PNM_LIB) \
$(BMP_LIB)
noinst_PROGRAMS = testpixbuf testpixbuf-drawable testanimation
noinst_PROGRAMS = testpixbuf testpixbuf-drawable testanimation testpixbuf-scale
DEPS = libgdk_pixbuf.la
INCLUDES = -I$(top_srcdir) -I$(top_builddir) \
......@@ -52,10 +54,12 @@ LDADDS = libgdk_pixbuf.la $(LIBART_LIBS) $(GLIB_LIBS) $(GTK_LIBS)
if INSIDE_GNOME_LIBS
testpixbuf_LDADD = $(LDADDS) $(LIBART_LIBS) -lgmodule
testpixbuf_drawable_LDADD = $(LDADDS)
testpixbuf_scale_LDADD = $(LDADDS)
testanimation_LDADD = $(LDADDS) $(LIBART_LIBS) -lgmodule
else
testpixbuf_LDADD = $(LDADDS) $(LIBART_LIBS) $(GNOME_LIBS) -lgmodule
testpixbuf_drawable_LDADD = $(LDADDS) $(GNOME_LIBS)
testpixbuf_scale_LDADD = $(LDADDS) $(GNOME_LIBS)
testanimation_LDADD = $(LDADDS) $(LIBART_LIBS) $(GNOME_LIBS) -lgmodule
endif
......@@ -83,6 +87,7 @@ libgdk_pixbuf_la_SOURCES = \
gdk-pixbuf-io.c \
gdk-pixbuf-loader.c \
gdk-pixbuf-render.c \
gdk-pixbuf-scale.c \
gdk-pixbuf-util.c \
$(CANVAS_SOURCEFILES)
......@@ -93,6 +98,8 @@ EXTRA_GNOME_LIBS = $(GNOME_LIBS)
endif
libgdk_pixbuf_la_LDFLAGS = -version-info 1:0:0 $(EXTRA_GNOME_LIBS)
libgdk_pixbuf_la_LIBADD = pixops/libpixops.la
libgdk_pixbufinclude_HEADERS = \
gdk-pixbuf.h \
......
#include "gdk-pixbuf.h"
#include "pixops/pixops.h"
#include "math.h"
/**
* gdk_pixbuf_scale:
* @src: a #GdkPixbuf
* @dest: the #GdkPixbuf into which to render the results
* @dest_x:
* @dest_y:
* @dest_width:
* @dest_height:
* @offset_x: the offset in the X direction (currently rounded to an integer)
* @offset_y: the offset in the Y direction (currently rounded to an integer)
* @scale_x: the scale factor in the X direction
* @scale_y: the scale factor in the Y direction
* @filter_level: the filter quality for the transformation.
*
* Transforms the image by source image by scaling by @scale_x and @scale_y then
* translating by @offset_x and @offset_y, then renders the rectangle
* (@dest,@dest_y,@dest_width,@dest_height) of the resulting image onto the
* destination drawable replacing the previous contents.
**/
void
gdk_pixbuf_scale (GdkPixbuf *src,
GdkPixbuf *dest,
int dest_x,
int dest_y,
int dest_width,
int dest_height,
double offset_x,
double offset_y,
double scale_x,
double scale_y,
ArtFilterLevel filter_level)
{
offset_x = floor(offset_x + 0.5);
offset_y = floor(offset_y + 0.5);
pixops_scale (dest->art_pixbuf->pixels + dest_y * dest->art_pixbuf->rowstride + dest_x * dest->art_pixbuf->n_channels,
-offset_x, -offset_y, dest_width - offset_x, dest_height - offset_y,
dest->art_pixbuf->rowstride, dest->art_pixbuf->n_channels, dest->art_pixbuf->has_alpha,
src->art_pixbuf->pixels, src->art_pixbuf->width, src->art_pixbuf->height,
src->art_pixbuf->rowstride, src->art_pixbuf->n_channels, src->art_pixbuf->has_alpha,
scale_x, scale_y, filter_level);
}
/**
* gdk_pixbuf_composite:
* @src: a #GdkPixbuf
* @dest: the #GdkPixbuf into which to render the results
* @dest_x:
* @dest_y:
* @dest_width:
* @dest_height:
* @offset_x: the offset in the X direction (currently rounded to an integer)
* @offset_y: the offset in the Y direction (currently rounded to an integer)
* @scale_x: the scale factor in the X direction
* @scale_y: the scale factor in the Y direction
* @filter_level: the filter quality for the transformation.
* @overall_alpha: overall alpha for source image (0..255)
*
* Transforms the image by source image by scaling by @scale_x and @scale_y then
* translating by @offset_x and @offset_y, then composites the rectangle
* (@dest,@dest_y,@dest_width,@dest_height) of the resulting image onto the
* destination drawable.
**/
void
gdk_pixbuf_composite (GdkPixbuf *src,
GdkPixbuf *dest,
int dest_x,
int dest_y,
int dest_width,
int dest_height,
double offset_x,
double offset_y,
double scale_x,
double scale_y,
ArtFilterLevel filter_level,
int overall_alpha)
{
offset_x = floor(offset_x + 0.5);
offset_y = floor(offset_y + 0.5);
pixops_composite (dest->art_pixbuf->pixels + dest_y * dest->art_pixbuf->rowstride + dest_x * dest->art_pixbuf->n_channels,
-offset_x, -offset_y, dest_width - offset_x, dest_height - offset_y,
dest->art_pixbuf->rowstride, dest->art_pixbuf->n_channels, dest->art_pixbuf->has_alpha,
src->art_pixbuf->pixels, src->art_pixbuf->width, src->art_pixbuf->height,
src->art_pixbuf->rowstride, src->art_pixbuf->n_channels, src->art_pixbuf->has_alpha,
scale_x, scale_y, filter_level, overall_alpha);
}
/**
* gdk_pixbuf_composite_color:
* @src: a #GdkPixbuf
* @dest: the #GdkPixbuf into which to render the results
* @dest_x:
* @dest_y:
* @dest_width:
* @dest_height:
* @offset_x: the offset in the X direction (currently rounded to an integer)
* @offset_y: the offset in the Y direction (currently rounded to an integer)
* @scale_x: the scale factor in the X direction
* @scale_y: the scale factor in the Y direction
* @filter_level: the filter quality for the transformation.
* @overall_alpha: overall alpha for source image (0..255)
* @check_x: the X offset for the checkboard (origin of checkboard is at -@check_x, -@check_y)
* @check_y: the Y offset for the checkboard
* @check_size: the size of checks in the checkboard (must be a power of two)
* @color1: the color of check at upper left
* @color2: the color of the other check
*
* Transforms the image by source image by scaling by @scale_x and @scale_y then
* translating by @offset_x and @offset_y, then composites the rectangle
* (@dest,@dest_y,@dest_width,@dest_height) of the resulting image with
* a checkboard of the colors @color1 and @color2 and renders it onto the
* destination drawable.
**/
void
gdk_pixbuf_composite_color (GdkPixbuf *src,
GdkPixbuf *dest,
int dest_x,
int dest_y,
int dest_width,
int dest_height,
double offset_x,
double offset_y,
double scale_x,
double scale_y,
ArtFilterLevel filter_level,
int overall_alpha,
int check_x,
int check_y,
int check_size,
art_u32 color1,
art_u32 color2)
{
offset_x = floor(offset_x + 0.5);
offset_y = floor(offset_y + 0.5);
pixops_composite_color (dest->art_pixbuf->pixels + dest_y * dest->art_pixbuf->rowstride + dest_x * dest->art_pixbuf->n_channels,
-offset_x, -offset_y, dest_width - offset_x, dest_height - offset_y,
dest->art_pixbuf->rowstride, dest->art_pixbuf->n_channels, dest->art_pixbuf->has_alpha,
src->art_pixbuf->pixels, src->art_pixbuf->width, src->art_pixbuf->height,
src->art_pixbuf->rowstride, src->art_pixbuf->n_channels, src->art_pixbuf->has_alpha,
scale_x, scale_y, filter_level, overall_alpha, check_x, check_y, check_size, color1, color2);
}
/**
* gdk_pixbuf_scale_simple:
* @src: a #GdkPixbuf
* @dest_width: the width of destination image
* @dest_height: the height of destination image
* @filter_level: the filter quality for the transformation.
*
* Scale the #GdkPixbuf @src to @dest_width x @dest_height and render the result into
* a new #GdkPixbuf.
*
* Return value: the new #GdkPixbuf
**/
GdkPixbuf *
gdk_pixbuf_scale_simple (GdkPixbuf *src,
int dest_width,
int dest_height,
ArtFilterLevel filter_level)
{
GdkPixbuf *dest = gdk_pixbuf_new (ART_PIX_RGB, src->art_pixbuf->has_alpha, 8, dest_width, dest_height);
gdk_pixbuf_scale (src, dest, 0, 0, dest_width, dest_height, 0, 0,
(double)dest_width / src->art_pixbuf->width,
(double)dest_height / src->art_pixbuf->height,
filter_level);
return dest;
}
/**
* gdk_pixbuf_composite_color_simple:
* @src: a #GdkPixbuf
* @dest_width: the width of destination image
* @dest_height: the height of destination image
* @filter_level: the filter quality for the transformation.
* @overall_alpha: overall alpha for source image (0..255)
* @check_size: the size of checks in the checkboard (must be a power of two)
* @color1: the color of check at upper left
* @color2: the color of the other check
*
* Scale the #GdkPixbuf @src to @dest_width x @dest_height composite the result with
* a checkboard of colors @color1 and @color2 and render the result into
* a new #GdkPixbuf.
*
* Return value: the new #GdkPixbuf
**/
GdkPixbuf *
gdk_pixbuf_composite_color_simple (GdkPixbuf *src,
int dest_width,
int dest_height,
ArtFilterLevel filter_level,
int overall_alpha,
int check_size,
art_u32 color1,
art_u32 color2)
{
GdkPixbuf *dest = gdk_pixbuf_new (ART_PIX_RGB, src->art_pixbuf->has_alpha, 8, dest_width, dest_height);
gdk_pixbuf_composite_color (src, dest, 0, 0, dest_width, dest_height, 0, 0,
(double)dest_width / src->art_pixbuf->width,
(double)dest_height / src->art_pixbuf->height,
filter_level, overall_alpha, 0, 0, check_size, color1, color2);
return dest;
}
......@@ -27,6 +27,7 @@
#include <libart_lgpl/art_misc.h>
#include <libart_lgpl/art_pixbuf.h>
#include <libart_lgpl/art_filterlevel.h>
#include <gdk/gdk.h>
#ifdef __cplusplus
......@@ -162,6 +163,62 @@ GdkPixbuf *gdk_pixbuf_get_from_drawable (GdkPixbuf *dest,
int dest_x, int dest_y,
int width, int height);
/* Scaling */
void gdk_pixbuf_scale (GdkPixbuf *src,
GdkPixbuf *dest,
int dest_x,
int dest_y,
int dest_width,
int dest_height,
double offset_x,
double offset_y,
double scale_x,
double scale_y,
ArtFilterLevel filter_level);
void gdk_pixbuf_composite (GdkPixbuf *src,
GdkPixbuf *dest,
int dest_x,
int dest_y,
int dest_width,
int dest_height,
double offset_x,
double offset_y,
double scale_x,
double scale_y,
ArtFilterLevel filter_level,
int overall_alpha);
void gdk_pixbuf_composite_color (GdkPixbuf *src,
GdkPixbuf *dest,
int dest_x,
int dest_y,
int dest_width,
int dest_height,
double offset_x,
double offset_y,
double scale_x,
double scale_y,
ArtFilterLevel filter_level,
int overall_alpha,
int check_x,
int check_y,
int check_size,
art_u32 color1,
art_u32 color2);
GdkPixbuf *gdk_pixbuf_scale_simple (GdkPixbuf *src,
int dest_width,
int dest_height,
ArtFilterLevel filter_level);
GdkPixbuf *gdk_pixbuf_composite_color_simple (GdkPixbuf *src,
int dest_width,
int dest_height,
ArtFilterLevel filter_level,
int overall_alpha,
int check_size,
art_u32 color1,
art_u32 color2);
/* Animation support */
GdkPixbufAnimation *gdk_pixbuf_animation_new_from_file (const char *filename);
......
Makefile
Makefile.in
.libs
.deps
*.lo
*.la
timescale
noinst_LTLIBRARIES = libpixops.la
INCLUDES = $(GLIB_CFLAGS)
bin_PROGRAMS = timescale
timescale_SOURCES = timescale.c
timescale_LDADD = libpixops.la $(GLIB_LIBS)
if USE_MMX
mmx_sources = \
have_mmx.S \
scale_line_22_33_mmx.S \
composite_line_22_4a4_mmx.S \
composite_line_color_22_4a4_mmx.S
endif
libpixops_la_SOURCES = \
pixops.c \
pixops.h \
pixops-internal.h \
$(mmx_sources)
.file "composite_line_22_4a4_mmx.S"
.version "01.01"
gcc2_compiled.:
.text
.align 16
.globl pixops_composite_line_22_4a4_mmx
.type pixops_composite_line_22_4a4_mmx,@function
/*
* Arguments
*
* weights: 8(%ebp)
* p: 12(%ebp) %esi
* q1: 16(%ebp)
* q2: 20(%ebp)
* xstep: 24(%ebp)
* p_end: 28(%ebp)
* xinit: 32(%ebp)
*
*/
pixops_composite_line_22_4a4_mmx:
/*
* Function call entry
*/
pushl %ebp
movl %esp,%ebp
subl $28,%esp
pushl %edi
pushl %esi
pushl %ebx
/* Locals:
* int x %ebx
* int x_scaled -24(%ebp)
*/
/*
* Setup
*/
/* Initialize variables */
movl 32(%ebp),%ebx
movl 32(%ebp),%edx
sarl $16,%edx
movl 12(%ebp),%esi
movl %edx,-24(%ebp)
cmpl %esi,28(%ebp)
je .out
/* Load initial values into %mm1, %mm3 */
shll $2, %edx
pxor %mm4, %mm4
movl 16(%ebp),%edi
movl (%edi, %edx), %eax
movd (%edi, %edx), %mm5