SVN revision: 2174
This commit is contained in:
Carsten Haitzler 2000-03-03 16:42:18 +00:00
parent 02bf3b4e28
commit b36488c507
7 changed files with 226 additions and 207 deletions

View File

@ -163,6 +163,7 @@ Imlib_Updates imlib_updates_append_updates(Imlib_Updates updates, Imlib_Updates
void imlib_image_flip_horizontal(void);
void imlib_image_flip_vertical(void);
void imlib_image_flip_diagonal(void);
void imlib_image_orientate(int orientation);
void imlib_image_blur(int radius);
void imlib_image_sharpen(int radius);
void imlib_image_tile_horizontal(void);

276
src/api.c
View File

@ -1186,7 +1186,48 @@ imlib_image_flip_diagonal(void)
return;
__imlib_DirtyImage(im);
__imlib_DirtyPixmapsForImage(im);
__imlib_FlipImageDiagonal(im);
__imlib_FlipImageDiagonal(im, 0);
}
void
imlib_image_orientate(int orientation)
{
ImlibImage *im;
CHECK_PARAM_POINTER("imlib_image_orientate", "image", ctxt_image);
CAST_IMAGE(im, ctxt_image);
if ((!(im->data)) && (im->loader) && (im->loader->load))
im->loader->load(im, NULL, 0, 1);
if (!(im->data))
return;
__imlib_DirtyImage(im);
__imlib_DirtyPixmapsForImage(im);
switch (orientation) {
default:
case 0:
break;
case 1:
__imlib_FlipImageDiagonal(im, 1);
break;
case 2:
__imlib_FlipImageBoth(im);
break;
case 3:
__imlib_FlipImageDiagonal(im, 2);
break;
case 4:
__imlib_FlipImageHoriz(im);
break;
case 5:
__imlib_FlipImageDiagonal(im, 3);
break;
case 6:
__imlib_FlipImageVert(im);
break;
case 7:
__imlib_FlipImageDiagonal(im, 0);
break;
}
}
void
@ -1982,184 +2023,81 @@ imlib_save_image_with_error_return(const char *filename,
}
Imlib_Image
imlib_create_rotated_image_test(double angle)
imlib_create_rotated_image(double angle)
{
ImlibImage *im, *im_old;
DATA32 *data;
int x, y, dx, dy, sz;
double x1, y1, d;
ImlibImage *im, *im_old;
DATA32 *data, *tmp;
int x, y, dx, dy, sz;
double x1, y1, d;
CHECK_PARAM_POINTER_RETURN("imlib_create_rotated_image", "image",
ctxt_image, NULL);
CAST_IMAGE(im_old, ctxt_image);
if ((!(im_old->data)) && (im_old->loader) && (im_old->loader->load))
im_old->loader->load(im_old, NULL, 0, 1);
if (!(im_old->data))
return NULL;
CHECK_PARAM_POINTER_RETURN("imlib_create_rotated_image", "image",
ctxt_image, NULL);
CAST_IMAGE(im_old, ctxt_image);
if ((!(im_old->data)) && (im_old->loader) && (im_old->loader->load))
im_old->loader->load(im_old, NULL, 0, 1);
if (!(im_old->data))
return NULL;
x1 = (double)(im_old->w) / 2.0;
y1 = (double)(im_old->h) / 2.0;
d = (double)(im_old->w < im_old->h ? im_old->w : im_old->h) / 2.0;
x1 -= sin(angle + atan(1.0)) * d;
y1 -= cos(angle + atan(1.0)) * d;
d = hypot((double)(im_old->w + 4), (double)(im_old->h + 4)) / sqrt(2.0);
sz = (int)(d * sqrt(2.0));
x = (int)(x1 * _ROTATE_PREC_MAX); y = (int)(y1 * _ROTATE_PREC_MAX);
dx = (int)(cos(angle) * _ROTATE_PREC_MAX);
dy = -(int)(sin(angle) * _ROTATE_PREC_MAX);
x1 = (double)(im_old->w) / 2.0 - sin(angle + atan(1.0)) * d;
y1 = (double)(im_old->h) / 2.0 - cos(angle + atan(1.0)) * d;
im = __imlib_CreateImage(sz, sz, NULL);
im->data = malloc(sz * sz * sizeof(DATA32));
if (!(im->data)) {
__imlib_FreeImage(im);
return NULL;
}
sz = (int)(d * sqrt(2.0));
x = (int)(x1 * _ROTATE_PREC_MAX);
y = (int)(y1 * _ROTATE_PREC_MAX);
dx = (int)(cos(angle) * _ROTATE_PREC_MAX);
dy = -(int)(sin(angle) * _ROTATE_PREC_MAX);
if (ctxt_anti_alias) {
__imlib_RotateAAInside(im_old->data, im->data,
im_old->w, im->w, sz, sz, x, y, dx, dy);
} else {
__imlib_RotateSampleInside(im_old->data, im->data,
im_old->w, im->w, sz, sz, x, y, dx, dy);
}
if (IMAGE_HAS_ALPHA(im_old))
SET_FLAG(im->flags, F_HAS_ALPHA);
if (ctxt_anti_alias) {
tmp = __imlib_AddTransBorders(im_old,
0, 0, im_old->w, im_old->h);
x += _ROTATE_PREC_MAX;
y += _ROTATE_PREC_MAX;
}
return (Imlib_Image)im;
im = __imlib_CreateImage(sz, sz, NULL);
im->data = calloc(sz * sz, sizeof(DATA32));
if (!(im->data)) {
__imlib_FreeImage(im);
return NULL;
}
if (ctxt_anti_alias) {
__imlib_RotateAA(tmp, im->data, im_old->w + 2,
im_old->w + 2, im_old->h + 2,
im->w, sz, sz, x, y, dx, dy);
free(tmp);
} else {
__imlib_RotateSample(im_old->data, im->data, im_old->w,
im_old->w, im_old->h, im->w, sz, sz, x, y, dx, dy);
}
SET_FLAG(im->flags, F_HAS_ALPHA);
return (Imlib_Image)im;
}
/*\ bigendian and littleendian byte-from-int macro's \*/
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define R_VAL(x) (*(((DATA8 *)&(x))+(0)))
#define G_VAL(x) (*(((DATA8 *)&(x))+(1)))
#define B_VAL(x) (*(((DATA8 *)&(x))+(2)))
#define A_VAL(x) (*(((DATA8 *)&(x))+(3)))
#elif __BYTE_ORDER == __BIG_ENDIAN
#define A_VAL(x) (*(((DATA8 *)&(x))+(0)))
#define B_VAL(x) (*(((DATA8 *)&(x))+(1)))
#define G_VAL(x) (*(((DATA8 *)&(x))+(2)))
#define R_VAL(x) (*(((DATA8 *)&(x))+(3)))
#elif __BYTE_ORDER == __PDP_ENDIAN
#define B_VAL(x) (*(((DATA8 *)&(x))+(0)))
#define A_VAL(x) (*(((DATA8 *)&(x))+(1)))
#define R_VAL(x) (*(((DATA8 *)&(x))+(2)))
#define G_VAL(x) (*(((DATA8 *)&(x))+(3)))
#else
#error Unknown byte endianness.
#endif
/*\ Helper: Expand an image in all directions with transparent borders
|*| Creates a new image, no caching (TODO)
|*| Why a separate function? Because the RGB channels of the borders
|*| are important (at least one pixel out, because of interpolation) \*/
static ImlibImage *
__imlib_AddTransBorders(ImlibImage *im_old, int width, int height)
void
imlib_blend_image_onto_image_at_angle(Imlib_Image source_image,
char merge_alpha,
int source_x, int source_y,
int source_width, int source_height,
int destination_x1, int destination_y1,
int destination_x2, int destination_y2)
{
ImlibImage *im;
int x, y, i;
DATA32 *p;
if (width < (im_old->w + 2)) return NULL;
if (height < (im_old->h + 2)) return NULL;
im = __imlib_CreateImage(width, height, NULL);
im->data = malloc(width * height * sizeof(DATA32));
if (!(im->data)) {
__imlib_FreeImage(im);
return NULL;
}
memset(im->data, 0, width * height * sizeof(DATA32));
x = (width - im_old->w) / 2;
y = (height - im_old->h) / 2;
for (i = im_old->h; --i >= 0; ) {
memcpy(im->data + x + ((y + i) * im->w),
im_old->data + (i * im_old->w),
im_old->w * sizeof(DATA32));
}
p = im->data + x + ((y - 1) * im->w);
for (i = im_old->w; --i >= 0; ) {
p[0] = p[im->w];
A_VAL(p[0]) = 0;
p++;
}
p = im->data + x + ((y + im_old->h) * im->w);
for (i = im_old->w; --i >= 0; ) {
p[0] = p[-im->w];
A_VAL(p[0]) = 0;
p++;
}
p = im->data + (x - 1) + ((y - 1) * im->w);
for (i = im_old->h + 2; --i >= 0; ) {
p[0] = p[1];
A_VAL(p[0]) = 0;
p += im->w;
}
p = im->data + (x + im_old->w) + ((y - 1) * im->w);
for (i = im_old->h + 2; --i >= 0; ) {
p[0] = p[-1];
A_VAL(p[0]) = 0;
p += im->w;
}
/*\ Useless, actually.. \*/
im->border.left = im_old->border.left + x;
im->border.top = im_old->border.top + y;
im->border.right = im_old->border.right + im->w - x - im_old->w;
im->border.bottom = im_old->border.bottom + im->h - y - im_old->h;
SET_FLAG(im->flags, F_HAS_ALPHA);
return im;
}
Imlib_Image
imlib_create_rotated_image_test2(double angle)
{
ImlibImage *im, *im_old, *im_tmp;
DATA32 *data;
int x, y, dx, dy, sz;
double x1, y1, d;
CHECK_PARAM_POINTER_RETURN("imlib_create_rotated_image", "image",
ctxt_image, NULL);
CAST_IMAGE(im_old, ctxt_image);
if ((!(im_old->data)) && (im_old->loader) && (im_old->loader->load))
im_old->loader->load(im_old, NULL, 0, 1);
if (!(im_old->data))
return NULL;
d = hypot((double)(im_old->w + 4), (double)(im_old->h + 4)) * sqrt(2.0);
im_tmp = __imlib_AddTransBorders(im_old, (int)d, (int)d);
if (!im_tmp)
return NULL;
d /= 2.0;
x1 = d - sin(angle + atan(1.0)) * d;
y1 = d - cos(angle + atan(1.0)) * d;
sz = (int)(d * sqrt(2.0));
x = (int)(x1 * _ROTATE_PREC_MAX); y = (int)(y1 * _ROTATE_PREC_MAX);
dx = (int)(cos(angle) * _ROTATE_PREC_MAX);
dy = -(int)(sin(angle) * _ROTATE_PREC_MAX);
im = __imlib_CreateImage(sz, sz, NULL);
im->data = malloc(sz * sz * sizeof(DATA32));
if (!(im->data)) {
__imlib_FreeImage(im);
return NULL;
}
if (ctxt_anti_alias) {
__imlib_RotateAAInside(im_tmp->data, im->data,
im_tmp->w, im->w, sz, sz, x, y, dx, dy);
} else {
__imlib_RotateSampleInside(im_tmp->data, im->data,
im_tmp->w, im->w, sz, sz, x, y, dx, dy);
}
if (IMAGE_HAS_ALPHA(im_tmp))
SET_FLAG(im->flags, F_HAS_ALPHA);
__imlib_FreeImage(im_tmp);
return (Imlib_Image)im;
ImlibImage *im_src, *im_dst;
CHECK_PARAM_POINTER("imlib_blend_image_onto_image_at_angle", "source_image", source_image);
CHECK_PARAM_POINTER("imlib_blend_image_onto_image_at_angle", "image", ctxt_image);
CAST_IMAGE(im_src, source_image);
CAST_IMAGE(im_dst, ctxt_image);
__imlib_DirtyImage(im_dst);
__imlib_DirtyPixmapsForImage(im_dst);
__imlib_BlendImageToImageAtAngle(im_src, im_dst, ctxt_anti_alias,
ctxt_blend, merge_alpha, source_x, source_y,
source_width, source_height, destination_x1,
destination_y1, destination_x2, destination_y2,
ctxt_color_modifier, ctxt_operation);
}
Imlib_Image

View File

@ -594,10 +594,10 @@ __imlib_render_str(ImlibImage *im, ImlibFont *fn, int drx, int dry, char *text,
__imlib_FlipImageVert(&im2);
break;
case 2: /* to down */
__imlib_FlipImageDiagonal(&im2);
__imlib_FlipImageDiagonal(&im2, 0);
break;
case 3: /* to up */
__imlib_FlipImageDiagonal(&im2);
__imlib_FlipImageDiagonal(&im2, 0);
__imlib_FlipImageHoriz(&im2);
__imlib_FlipImageVert(&im2);
break;

View File

@ -28,6 +28,9 @@ __imlib_FlipImageHoriz(ImlibImage *im)
p2--;
}
}
x = im->border.left;
im->border.left = im->border.right;
im->border.right = x;
}
void
@ -49,37 +52,107 @@ __imlib_FlipImageVert(ImlibImage *im)
p2++;
}
}
x = im->border.top;
im->border.top = im->border.bottom;
im->border.bottom = x;
}
void
__imlib_FlipImageDiagonal(ImlibImage *im)
__imlib_FlipImageBoth(ImlibImage *im)
{
DATA32 *p1, *p2, *data;
int x, y, tmp;
DATA32 *p1, *p2, tmp;
int x;
data = malloc(im->w * im->h * sizeof(DATA32));
p1 = im->data;
for (y = im->h - 1; y >= 0; y--)
{
p2 = data + y;
for (x = 0; x < im->w; x++)
p2 = im->data + (im->h * im->w) - 1;
for (x = (im->w * im->h) / 2; --x >= 0; )
{
*p2 = *p1;
p2 += im->h;
tmp = *p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2--;
}
x = im->border.top;
im->border.top = im->border.bottom;
im->border.bottom = x;
x = im->border.left;
im->border.left = im->border.right;
im->border.right = x;
}
free(im->data);
im->data = data;
tmp = im->w;
im->w = im->h;
im->h = tmp;
/*\ Directions (source is right/down):
|*| 0 = down/right (flip over ul-dr diagonal)
|*| 1 = down/left (rotate 90 degrees clockwise)
|*| 2 = up/right (rotate 90 degrees counterclockwise)
|*| 3 = up/left (flip over ur-ll diagonal)
\*/
void
__imlib_FlipImageDiagonal(ImlibImage *im, int direction)
{
DATA32 *data, *to, *from;
int x, y, w, hw, tmp;
data = malloc(im->w * im->h * sizeof(DATA32));
from = im->data;
w = im->h;
im->h = im->w;
im->w = w;
hw = w * im->h;
switch (direction) {
default:
case 0: /*\ DOWN_RIGHT \*/
tmp = im->border.top;
im->border.top = im->border.left;
im->border.left = tmp;
tmp = im->border.bottom;
im->border.bottom = im->border.right;
im->border.right = tmp;
to = data;
hw = -hw + 1;
break;
case 1: /*\ DOWN_LEFT \*/
tmp = im->border.top;
im->border.top = im->border.left;
im->border.left = im->border.bottom;
im->border.bottom = im->border.right;
im->border.right = tmp;
to = data + w - 1;
hw = -hw - 1;
break;
case 2: /*\ UP_RIGHT \*/
tmp = im->border.top;
im->border.top = im->border.right;
im->border.right = im->border.bottom;
im->border.bottom = im->border.left;
im->border.left = tmp;
to = data + hw - w;
w = -w;
hw = hw + 1;
break;
case 3: /*\ UP_LEFT \*/
tmp = im->border.top;
im->border.top = im->border.right;
im->border.right = tmp;
tmp = im->border.bottom;
im->border.bottom = im->border.left;
im->border.left = tmp;
to = data + hw - 1;
w = -w;
hw = hw - 1;
break;
}
from = im->data;
for (x = im->w; --x >= 0; ) {
for (y = im->h; --y >= 0; ) {
*to = *from;
from++;
to += w;
}
to += hw;
}
free(im->data);
im->data = data;
}
void

View File

@ -2,7 +2,8 @@
#define __RGBADRAW 1
void __imlib_FlipImageHoriz(ImlibImage *im);
void __imlib_FlipImageVert(ImlibImage *im);
void __imlib_FlipImageDiagonal(ImlibImage *im);
void __imlib_FlipImageBoth(ImlibImage *im);
void __imlib_FlipImageDiagonal(ImlibImage *im, int direction);
void __imlib_BlurImage(ImlibImage *im, int rad);
void __imlib_SharpenImage(ImlibImage *im, int rad);
void __imlib_TileImageHoriz(ImlibImage *im);

View File

@ -1,6 +1,7 @@
#include "common.h"
#include "rotate.h"
#include "blend.h"
/*\ I have no idea which of these two is faster..
|*| The first one doesn't branch, the second one doesn't multiply..

View File

@ -8,6 +8,7 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
/*
#include <sys/time.h>
#include "common.h"
@ -367,8 +368,8 @@ int main (int argc, char **argv)
{
case Expose:
up = imlib_update_append_rect(up,
ev.xexpose.x, ev.xexpose.y,
ev.xexpose.width, ev.xexpose.height);
ev.xexpose.x, ev.xexpose.y,
ev.xexpose.width, ev.xexpose.height);
break;
case ButtonRelease:
exit(0);
@ -411,25 +412,28 @@ int main (int argc, char **argv)
else if (rotate)
{
Imlib_Image rotim;
double ang = (double)x / 100.0;
int rw, rh, rx, ry;
double s, c;
int x1, y1, x2, y2, w, h;
w = imlib_image_get_width();
h = imlib_image_get_height();
s = sin(6.2831853 * (double)y / (double)h);
c = cos(6.2831853 * (double)y / (double)h);
x1 = (w - w * c + h * s) / 2;
y1 = (h - h * c - w * s) / 2;
x2 = (w + w * c - h * s) / 2;
y2 = (h + h * c + w * s) / 2;
imlib_context_set_blend(1);
imlib_context_set_image(im_bg);
rotim = imlib_create_rotated_image_test2(ang);
imlib_context_set_image(rotim);
rw = imlib_image_get_width();
rh = imlib_image_get_height();
rx = (w - rw) / 2;
ry = (h - rh) / 2;
imlib_context_set_image(im);
imlib_blend_image_onto_image(rotim, 0,
0, 0, rw, rh,
rx, ry, rw, rh);
imlib_context_set_image(rotim);
imlib_free_image_and_decache();
imlib_context_set_image(im);
up = imlib_update_append_rect(up, rx, ry, rw, rh);
imlib_blend_image_onto_image_at_angle(im_bg, 0,
0, 0,
imlib_image_get_width(),
imlib_image_get_height(),
x1, y1, x2, y2);
up = imlib_update_append_rect(up, 0, 0,
imlib_image_get_width(),
imlib_image_get_height());
}
{
Imlib_Updates uu;
@ -554,6 +558,7 @@ int main (int argc, char **argv)
}
else
{
pixels = 0;
for (i = 0; i < w; i++)
{
imlib_render_image_on_drawable_at_size(0, 0, w, h);
@ -572,7 +577,7 @@ int main (int argc, char **argv)
j += 1000000;
}
sec = (double)i + ((double)j / 1000000);
printf("%3.3f sec\n", sec);
printf("%3.3f sec, %3.3f M pixels (%i)\n", sec, (double)pixels / 1000000, pixels);
printf("%3.3f Mpixels / sec\n", (double)(pixels) / (sec * 1000000));
return 0;
}