2022-06-26 11:06:35 +02:00
|
|
|
|
/*
|
|
|
|
|
bitblt.c
|
|
|
|
|
--------
|
|
|
|
|
|
|
|
|
|
Dans ce module, il y a <EFBFBD>normement d'optimisations de vitesse
|
|
|
|
|
<EFBFBD> faire. Je le sais. Mais mon neurone est en surcharge...
|
|
|
|
|
-------------------------------------------------------
|
|
|
|
|
voir aussi: insert.c
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
2022-06-27 00:48:18 +02:00
|
|
|
|
#include "../tthimage.h"
|
2022-06-26 11:06:35 +02:00
|
|
|
|
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
|
/*
|
|
|
|
|
* la structure 'z' decrit les pixels sources (dimensions et position)
|
|
|
|
|
* et les parametres x et y disent ou recopier les pixels dans l'image
|
|
|
|
|
* de destination.
|
|
|
|
|
*/
|
2023-10-11 22:36:16 +02:00
|
|
|
|
int Image_get_rect(Image_Desc *s, Image_Rect *z, Image_Desc *d, int x, int y)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
int xfoo, yfoo; /* oh! des 'foo' 2D :-) */
|
|
|
|
|
int xs, ys;
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
|
fprintf(stderr, ">>> %s ( %p %p %p %d %d )\n", __func__, s, z, d, x, y);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* NEED MORE EXPLANATION XXX !
|
|
|
|
|
*/
|
2022-06-26 11:06:35 +02:00
|
|
|
|
#if DEBUG_LEVEL > 1
|
|
|
|
|
fprintf(stderr, "GET RECT src %p %4d, %4d, %4d, %4d\n",
|
|
|
|
|
s, z->x, z->y, z->w, z->h);
|
|
|
|
|
fprintf(stderr, " dst %p %4d, %4d\n", d, x, y);
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
if ( (z->w > d->width) || (z->h > d->height) ) {
|
|
|
|
|
fprintf(stderr, "%s: oups, bad rect\n", __func__);
|
2022-06-26 11:06:35 +02:00
|
|
|
|
return 666;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
for (yfoo=0; yfoo<z->h; yfoo++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
ys = yfoo + z->y;
|
|
|
|
|
if (ys<0 || ys>s->height-1)
|
|
|
|
|
continue;
|
2023-10-11 22:36:16 +02:00
|
|
|
|
for (xfoo=0; xfoo<z->w; xfoo++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
xs = xfoo + z->x;
|
|
|
|
|
if (xs<0 || xs>s->width-1)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Image_pixel_copy(s, xs, ys, d, x+xfoo, y+yfoo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
|
/*
|
2023-10-11 22:36:16 +02:00
|
|
|
|
* 2023-09-30: je comprend rien a ce truc !
|
|
|
|
|
*
|
2022-06-26 11:06:35 +02:00
|
|
|
|
* recopie d'un rectangle d'une image source par dessus
|
|
|
|
|
* une image destination.
|
|
|
|
|
*/
|
2023-10-11 22:36:16 +02:00
|
|
|
|
int Image_put_rect(Image_Desc *s, Image_Rect *z, Image_Desc *d, int x, int y)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
int xfoo, yfoo;
|
|
|
|
|
int xs, ys, xd, yd;
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
|
fprintf(stderr, ">>> %s ( %p %p %p %d %d )\n", __func__, s, z, d, x, y);
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-06-26 11:06:35 +02:00
|
|
|
|
#if DEBUG_LEVEL > 1
|
|
|
|
|
fprintf(stderr, "PUT RECT src %p %4d, %4d, %4d, %4d\n",
|
|
|
|
|
s, z->x, z->y, z->w, z->h);
|
|
|
|
|
fprintf(stderr, " dst %p %4d, %4d\n", d, x, y);
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
for (yfoo=0; yfoo<z->h; yfoo++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
ys = yfoo + z->y;
|
|
|
|
|
if (ys<0 || ys>s->height-1)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
yd = yfoo + y;
|
|
|
|
|
if (yd<0 || yd>d->height-1)
|
|
|
|
|
continue;
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
for (xfoo=0; xfoo<z->w; xfoo++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
xs = xfoo + z->x;
|
|
|
|
|
if (xs<0 || xs>s->width-1)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
xd = xfoo + x;
|
|
|
|
|
if (xd<0 || xd>d->width-1)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Image_pixel_copy(s, xs, ys, d, xd, yd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
return FUNC_IS_ALPHA; /* AH BRAVO */
|
2022-06-26 11:06:35 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
|
/*
|
|
|
|
|
* coredumper dlmkt !
|
|
|
|
|
*/
|
2023-10-11 22:36:16 +02:00
|
|
|
|
int Image_copy_rect(Image_Desc *s, Image_Rect *z, Image_Desc *d, int x, int y)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
int xs, ys, xd, yd, xx, yy;
|
|
|
|
|
int foo;
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
fprintf(stderr, ">>> %s ( %p %p %p %d %d )\n", __func__, s, z, d, x, y );
|
2022-06-26 11:06:35 +02:00
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
if (d->magic != MAGIC_OF_IMAGE) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
fprintf(stderr, "%s: need Dead Beef\n", __func__);
|
|
|
|
|
return NOT_AN_IMAGE_DESC;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foo = 0;
|
2023-10-11 22:36:16 +02:00
|
|
|
|
for (yy=0; yy<z->h; yy++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
ys = yy + z->y;
|
|
|
|
|
if (ys<0 || ys>=s->height)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
yd = y + yy;
|
|
|
|
|
if (yd<0 || yd>=d->height)
|
|
|
|
|
continue;
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
for (xx=0; xx<z->w; xx++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
xs = xx + z->x;
|
|
|
|
|
if (xs<0 || xs>=s->width)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
xd = x + xx;
|
|
|
|
|
if (xd<0 || xd>=d->width)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Image_pixel_copy(s, xs, ys, d, xd, yd);
|
|
|
|
|
foo++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FUNC_IS_BETA;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
|
/*
|
|
|
|
|
* nouveau 11 jan 00 cree a la rache pour extraitre des images
|
|
|
|
|
* 256x256 afin de tester FFTW :-)
|
|
|
|
|
*
|
|
|
|
|
* 23 dec 01 found a coredump if src image is too small
|
|
|
|
|
*
|
|
|
|
|
*/
|
2023-10-11 22:36:16 +02:00
|
|
|
|
Image_Desc *Image_create_subimg(Image_Desc *src, Image_Rect *r, int gray)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
Image_Desc *clone;
|
|
|
|
|
int x,y,xs, ys;
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, src, r, gray);
|
|
|
|
|
|
2022-06-26 11:06:35 +02:00
|
|
|
|
/*
|
|
|
|
|
* sanities controls...
|
|
|
|
|
*/
|
2023-10-11 22:36:16 +02:00
|
|
|
|
if (src->type != IMAGE_RGB) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
fprintf(stderr, "'%s' work only on RGB images\n", __func__);
|
|
|
|
|
exit(5);
|
|
|
|
|
}
|
2023-10-11 22:36:16 +02:00
|
|
|
|
if ( (r->x<0) || (r->y<0) ) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
fprintf(stderr, "create_subimg, rect(%d,%d,%d,%d) iznotgoud\n",
|
|
|
|
|
r->x, r->y, r->w, r->h);
|
|
|
|
|
exit(5);
|
|
|
|
|
}
|
|
|
|
|
/* MUST CHECK THAT SOURCE IMAGE IS BIG ENOUGH ! */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* now, we allocate the new image...
|
|
|
|
|
*/
|
|
|
|
|
clone = Image_alloc(r->w, r->h, src->type);
|
2023-10-11 22:36:16 +02:00
|
|
|
|
if (clone == NULL) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
fprintf(stderr, "CreateSubImage: can't alloc memory...\n");
|
|
|
|
|
exit(5);
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
for (x=0; x<r->w; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
xs = x + r->x;
|
2023-10-11 22:36:16 +02:00
|
|
|
|
for (y=0; y<r->h; y++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
ys = y + r->y;
|
|
|
|
|
/*printf("dst %4d %4d ", x, y); */
|
|
|
|
|
/*printf("src %4d %4d ", xs, ys); */
|
|
|
|
|
|
2023-10-11 22:36:16 +02:00
|
|
|
|
if (ys<0 || ys>src->width) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
Image_plotRGB(clone, x, y, gray, gray, gray);
|
|
|
|
|
}
|
2023-10-11 22:36:16 +02:00
|
|
|
|
else {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
/* XXX calling this func is a nasty cpu sucker,
|
|
|
|
|
* so we have to go to a nasty optimize trick */
|
|
|
|
|
/* XXX Image_pixel_copy(src, xs, ys, clone, x, y); */
|
|
|
|
|
(clone->Rpix[y])[x] = (src->Rpix[ys])[xs];
|
|
|
|
|
(clone->Gpix[y])[x] = (src->Gpix[ys])[xs];
|
|
|
|
|
(clone->Bpix[y])[x] = (src->Bpix[ys])[xs];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return clone;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
|
/*
|
|
|
|
|
http://highwire.atari-users.net/cgi-bin/cvsweb/~checkout~lib/gemlib/rc_intersect.c?rev=1.2
|
|
|
|
|
*/
|
|
|
|
|
#define max(a,b) ((a)>(b)?(a):(b))
|
|
|
|
|
#define min(a,b) ((a)<(b)?(a):(b))
|
|
|
|
|
int
|
|
|
|
|
rc_intersect (const Image_Rect * r1, Image_Rect * r2)
|
|
|
|
|
{
|
|
|
|
|
int tx, ty, tw, th, ret;
|
|
|
|
|
|
|
|
|
|
tx = max (r2->x, r1->x);
|
|
|
|
|
tw = min (r2->x + r2->w, r1->x + r1->w) - tx;
|
|
|
|
|
|
|
|
|
|
ret = (0 < tw);
|
|
|
|
|
if (ret)
|
|
|
|
|
{
|
|
|
|
|
ty = max (r2->y, r1->y);
|
|
|
|
|
th = min (r2->y + r2->h, r1->y + r1->h) - ty;
|
|
|
|
|
|
|
|
|
|
ret = (0 < th);
|
|
|
|
|
if (ret)
|
|
|
|
|
{
|
|
|
|
|
r2->x = tx;
|
|
|
|
|
r2->y = ty;
|
|
|
|
|
r2->w = tw;
|
|
|
|
|
r2->h = th;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
|
|