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_horizontal(void);
void imlib_image_flip_vertical(void); void imlib_image_flip_vertical(void);
void imlib_image_flip_diagonal(void); void imlib_image_flip_diagonal(void);
void imlib_image_orientate(int orientation);
void imlib_image_blur(int radius); void imlib_image_blur(int radius);
void imlib_image_sharpen(int radius); void imlib_image_sharpen(int radius);
void imlib_image_tile_horizontal(void); void imlib_image_tile_horizontal(void);

276
src/api.c
View File

@ -1186,7 +1186,48 @@ imlib_image_flip_diagonal(void)
return; return;
__imlib_DirtyImage(im); __imlib_DirtyImage(im);
__imlib_DirtyPixmapsForImage(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 void
@ -1982,184 +2023,81 @@ imlib_save_image_with_error_return(const char *filename,
} }
Imlib_Image Imlib_Image
imlib_create_rotated_image_test(double angle) imlib_create_rotated_image(double angle)
{ {
ImlibImage *im, *im_old; ImlibImage *im, *im_old;
DATA32 *data; DATA32 *data, *tmp;
int x, y, dx, dy, sz; int x, y, dx, dy, sz;
double x1, y1, d; double x1, y1, d;
CHECK_PARAM_POINTER_RETURN("imlib_create_rotated_image", "image", CHECK_PARAM_POINTER_RETURN("imlib_create_rotated_image", "image",
ctxt_image, NULL); ctxt_image, NULL);
CAST_IMAGE(im_old, ctxt_image); CAST_IMAGE(im_old, ctxt_image);
if ((!(im_old->data)) && (im_old->loader) && (im_old->loader->load)) if ((!(im_old->data)) && (im_old->loader) && (im_old->loader->load))
im_old->loader->load(im_old, NULL, 0, 1); im_old->loader->load(im_old, NULL, 0, 1);
if (!(im_old->data)) if (!(im_old->data))
return NULL; return NULL;
x1 = (double)(im_old->w) / 2.0; d = hypot((double)(im_old->w + 4), (double)(im_old->h + 4)) / sqrt(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;
sz = (int)(d * sqrt(2.0)); x1 = (double)(im_old->w) / 2.0 - sin(angle + atan(1.0)) * d;
x = (int)(x1 * _ROTATE_PREC_MAX); y = (int)(y1 * _ROTATE_PREC_MAX); y1 = (double)(im_old->h) / 2.0 - cos(angle + atan(1.0)) * d;
dx = (int)(cos(angle) * _ROTATE_PREC_MAX);
dy = -(int)(sin(angle) * _ROTATE_PREC_MAX);
im = __imlib_CreateImage(sz, sz, NULL); sz = (int)(d * sqrt(2.0));
im->data = malloc(sz * sz * sizeof(DATA32)); x = (int)(x1 * _ROTATE_PREC_MAX);
if (!(im->data)) { y = (int)(y1 * _ROTATE_PREC_MAX);
__imlib_FreeImage(im); dx = (int)(cos(angle) * _ROTATE_PREC_MAX);
return NULL; dy = -(int)(sin(angle) * _ROTATE_PREC_MAX);
}
if (ctxt_anti_alias) { if (ctxt_anti_alias) {
__imlib_RotateAAInside(im_old->data, im->data, tmp = __imlib_AddTransBorders(im_old,
im_old->w, im->w, sz, sz, x, y, dx, dy); 0, 0, im_old->w, im_old->h);
} else { x += _ROTATE_PREC_MAX;
__imlib_RotateSampleInside(im_old->data, im->data, y += _ROTATE_PREC_MAX;
im_old->w, im->w, sz, sz, x, y, dx, dy); }
}
if (IMAGE_HAS_ALPHA(im_old))
SET_FLAG(im->flags, F_HAS_ALPHA);
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 \*/ void
#if __BYTE_ORDER == __LITTLE_ENDIAN imlib_blend_image_onto_image_at_angle(Imlib_Image source_image,
#define R_VAL(x) (*(((DATA8 *)&(x))+(0))) char merge_alpha,
#define G_VAL(x) (*(((DATA8 *)&(x))+(1))) int source_x, int source_y,
#define B_VAL(x) (*(((DATA8 *)&(x))+(2))) int source_width, int source_height,
#define A_VAL(x) (*(((DATA8 *)&(x))+(3))) int destination_x1, int destination_y1,
#elif __BYTE_ORDER == __BIG_ENDIAN int destination_x2, int destination_y2)
#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)
{ {
ImlibImage *im; ImlibImage *im_src, *im_dst;
int x, y, i;
DATA32 *p; 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);
if (width < (im_old->w + 2)) return NULL; CAST_IMAGE(im_src, source_image);
if (height < (im_old->h + 2)) return NULL; CAST_IMAGE(im_dst, ctxt_image);
__imlib_DirtyImage(im_dst);
im = __imlib_CreateImage(width, height, NULL); __imlib_DirtyPixmapsForImage(im_dst);
im->data = malloc(width * height * sizeof(DATA32)); __imlib_BlendImageToImageAtAngle(im_src, im_dst, ctxt_anti_alias,
if (!(im->data)) { ctxt_blend, merge_alpha, source_x, source_y,
__imlib_FreeImage(im); source_width, source_height, destination_x1,
return NULL; destination_y1, destination_x2, destination_y2,
} ctxt_color_modifier, ctxt_operation);
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;
} }
Imlib_Image Imlib_Image

View File

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

View File

@ -28,6 +28,9 @@ __imlib_FlipImageHoriz(ImlibImage *im)
p2--; p2--;
} }
} }
x = im->border.left;
im->border.left = im->border.right;
im->border.right = x;
} }
void void
@ -49,37 +52,107 @@ __imlib_FlipImageVert(ImlibImage *im)
p2++; p2++;
} }
} }
x = im->border.top;
im->border.top = im->border.bottom;
im->border.bottom = x;
} }
void void
__imlib_FlipImageDiagonal(ImlibImage *im) __imlib_FlipImageBoth(ImlibImage *im)
{ {
DATA32 *p1, *p2, *data; DATA32 *p1, *p2, tmp;
int x, y, tmp; int x;
data = malloc(im->w * im->h * sizeof(DATA32));
p1 = im->data; p1 = im->data;
for (y = im->h - 1; y >= 0; y--) p2 = im->data + (im->h * im->w) - 1;
{ for (x = (im->w * im->h) / 2; --x >= 0; )
p2 = data + y;
for (x = 0; x < im->w; x++)
{ {
*p2 = *p1; tmp = *p1;
p2 += im->h; *p1 = *p2;
*p2 = tmp;
p1++; 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; /*\ Directions (source is right/down):
tmp = im->w; |*| 0 = down/right (flip over ul-dr diagonal)
im->w = im->h; |*| 1 = down/left (rotate 90 degrees clockwise)
im->h = tmp; |*| 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; tmp = im->border.top;
im->border.top = im->border.left; im->border.top = im->border.left;
im->border.left = tmp; im->border.left = tmp;
tmp = im->border.bottom; tmp = im->border.bottom;
im->border.bottom = im->border.right; im->border.bottom = im->border.right;
im->border.right = tmp; 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 void

View File

@ -2,7 +2,8 @@
#define __RGBADRAW 1 #define __RGBADRAW 1
void __imlib_FlipImageHoriz(ImlibImage *im); void __imlib_FlipImageHoriz(ImlibImage *im);
void __imlib_FlipImageVert(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_BlurImage(ImlibImage *im, int rad);
void __imlib_SharpenImage(ImlibImage *im, int rad); void __imlib_SharpenImage(ImlibImage *im, int rad);
void __imlib_TileImageHoriz(ImlibImage *im); void __imlib_TileImageHoriz(ImlibImage *im);

View File

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

View File

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