[EXAMPLES]

* NEW: The Fractal example now uses eight background tasks to draw the 
  fractal.

[GB.IMAGE]
* NEW: Image.Pixels is a new property that allows to return the image 
  pixels as an integer array, and to set the image pixels from an integer
  array.


git-svn-id: svn://localhost/gambas/trunk@5687 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2013-05-30 21:16:09 +00:00
parent 21f0837572
commit 45c481c1b4
10 changed files with 227 additions and 310 deletions

View file

@ -11,43 +11,51 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: FFractal.class:403
msgid "Fast"
msgstr "Rapide"
#: .project:1
msgid "Fractal"
msgstr ""
msgstr "Fractal"
#: .project:2
msgid "Mandelbrot Fractal with Just-In-Time compilation"
msgstr ""
msgstr "Fractale de Mandelbort avec compilation Just-In-Time"
#: FFractal.class:392
msgid "Press F to activate Just-In-Time compilation"
msgstr "Appuyez sur F pour activer la compilation \"juste à-temps\""
#: FFractal.class:390
#: FFractal.class:95
msgid "Press F to deactivate Just-In-Time compilation"
msgstr "Appuyez sur F pour désactiver la compilation \"juste à-temps\""
#: FFractal.class:397
#: FFractal.class:97
msgid "Press F to activate Just-In-Time compilation"
msgstr "Appuyez sur F pour activer la compilation \"juste à-temps\""
#: FFractal.class:102
msgid "Press R to hide rectangle optimization"
msgstr "Appuyez sur R pour cacher l'optimisation par rectangles"
#: FFractal.class:399
#: FFractal.class:104
msgid "Press R to show rectangle optimization"
msgstr "Appuyez sur R pour afficher l'optimisation par rectangles"
#: FFractal.class:403
#: FFractal.class:108
msgid "Fast"
msgstr "Rapide"
#: FFractal.class:108
msgid "Max"
msgstr "Max"
#: FFractal.class:108
msgid "Slow"
msgstr "Lente"
#: FFractal.class:403
#: FFractal.class:108
msgid "Speed"
msgstr "Vitesse"
#: FFractal.class:403
#: FFractal.class:108
msgid "Tasks"
msgstr "Tâches"
#: FFractal.class:108
msgid "Zoom"
msgstr "Zoom"

View file

@ -1,9 +1,9 @@
# Gambas Project File 3.0
# Compiled with Gambas 3.3.90
# Compiled with Gambas 3.4.90
Title=Fractal
Startup=FFractal
Icon=icon.png
Version=3.3.90
Version=3.4.90
VersionFile=1
Component=gb.image
Component=gb.gui

View file

@ -13,288 +13,47 @@ Private $YY As Float
Private $bFast As Boolean
Private $bRect As Boolean
Fast Private Sub FastDrawFractalRect(hImage As Image, XO As Float, YO As Float, SF As Float, X As Integer, Y As Integer, W As Integer, H As Integer)
Private NTASK As Integer = 8
Private $aTask As New FractalTask[NTASK]
Private $aResult As New Image[NTASK]
Public Sub FractalTask_Kill()
Dim I, J, K, C, CC As Integer
Dim XF, YF, XF0, YF0, XF1, YF1 As Float
Dim ZX, ZY, T As Float
Dim bSame As Boolean
Dim bRect As Boolean = $bRect
XF0 = XO + X * SF
YF0 = YO + Y * SF
If W <= 4 And If H <= 4 Then Goto CALC_ALL
XF1 = XF0 + (W - 1) * SF
YF1 = YF0 + (H - 1) * SF
If Sgn(XF0) + Sgn(XF1) Or If Sgn(YF0) + Sgn(YF1) Then
C = 0
XF = XF0
YF = YF0
I = X
J = Y
GoSub CALC_POINT
CC = C
bSame = True
'XF += SF
For I = X To X + W - 1
YF = YF0
J = Y
GoSub CALC_POINT
YF = YF1
J = Y + H - 1
GoSub CALC_POINT
XF += SF
Next
YF = YF0 + SF
For J = Y + 1 To Y + H - 2
XF = XF0
I = X
GoSub CALC_POINT
XF = XF1
I = X + W - 1
GoSub CALC_POINT
YF += SF
Next
If bSame Then
If CC Then hImage.FillRect(X + 1, Y + 1, W - 2, H - 2, CC)
If bRect Then
hImage.PaintRect(X + 1, Y + 1, W - 2, H - 2, &HC0FFFFFF&)
Endif
Return
Endif
Inc X
Inc Y
W -= 2
H -= 2
Dim hTask As FractalTask = Last
Dim aResult As Integer[]
Dim hImage As Image
'Print hTask.Index; ": *KILL*"
Try aResult = hTask.Value
If aResult Then
hImage = New Image(hTask.Width, hTask.Height)
hImage.Pixels = aResult
$aResult[hTask.Index] = hImage
dwgFractal.Refresh
Endif
If W >= H Then
FastDrawFractalRect(hImage, XO, YO, SF, X, Y, W \ 2, H)
FastDrawFractalRect(hImage, XO, YO, SF, X + (W \ 2), Y, W - (W \ 2), H)
Else
FastDrawFractalRect(hImage, XO, YO, SF, X, Y, W, H \ 2)
FastDrawFractalRect(hImage, XO, YO, SF, X, Y + (H \ 2), W, H - (H \ 2))
Endif
' FastDrawFractalRect(hImage, XO, YO, SF, X, Y, W \ 2, H \ 2)
' FastDrawFractalRect(hImage, XO, YO, SF, X + (W \ 2), Y, W - (W \ 2), H \ 2)
' FastDrawFractalRect(hImage, XO, YO, SF, X, Y + (H \ 2), W \ 2, H - (H \ 2))
' FastDrawFractalRect(hImage, XO, YO, SF, X + (W \ 2), Y + (H \ 2), W - (W \ 2), H - (H \ 2))
Return
CALC_ALL:
XF = XF0
For I = X To X + W - 1
YF = YF0
For J = Y To Y + H - 1
ZX = 0
ZY = 0
For K = 0 To ITER_MAX - 1
T = ZX * ZX - ZY * ZY + XF
ZY = 2 * ZX * ZY + YF
If ((T * T) + (ZY * ZY)) > 4 Then Break
ZX = T
Next
If K < ITER_MAX Then hImage[I, J] = $aColor[K And 63]
YF += SF
Next
XF += SF
Next
Return
CALC_POINT:
ZX = 0
ZY = 0
For K = 0 To ITER_MAX - 1
T = ZX * ZX - ZY * ZY + XF
ZY = 2 * ZX * ZY + YF
If ((T * T) + (ZY * ZY)) > 4 Then Break
ZX = T
Next
If K < ITER_MAX Then
K = K And 63
C = $aColor[K]
If C <> CC Then bSame = False
hImage[I, J] = C
Else
C = 0
If C <> CC Then bSame = False
Endif
Return
End
Private Sub DrawFractalRect(hImage As Image, XO As Float, YO As Float, SF As Float, X As Integer, Y As Integer, W As Integer, H As Integer)
Dim I, J, K, C, CC As Integer
Dim XF, YF, XF0, YF0, XF1, YF1 As Float
Dim ZX, ZY, T As Float
Dim bSame As Boolean
Dim bRect As Boolean = $bRect
XF0 = XO + X * SF
YF0 = YO + Y * SF
If W <= 4 And If H <= 4 Then Goto CALC_ALL
XF1 = XF0 + (W - 1) * SF
YF1 = YF0 + (H - 1) * SF
If Sgn(XF0) + Sgn(XF1) Or If Sgn(YF0) + Sgn(YF1) Then
C = 0
XF = XF0
YF = YF0
I = X
J = Y
GoSub CALC_POINT
CC = C
bSame = True
XF += SF
For I = X To X + W - 1
YF = YF0
J = Y
GoSub CALC_POINT
YF = YF1
J = Y + H - 1
GoSub CALC_POINT
XF += SF
Next
YF = YF0 + SF
For J = Y + 1 To Y + H - 2
XF = XF0
I = X
GoSub CALC_POINT
XF = XF1
I = X + W - 1
GoSub CALC_POINT
YF += SF
Next
If bSame Then
If CC Then hImage.FillRect(X + 1, Y + 1, W - 2, H - 2, CC)
If bRect Then
hImage.PaintRect(X + 1, Y + 1, W - 2, H - 2, &HC0FFFFFF&)
Endif
Return
Endif
Inc X
Inc Y
W -= 2
H -= 2
Endif
If W >= H Then
DrawFractalRect(hImage, XO, YO, SF, X, Y, W \ 2, H)
DrawFractalRect(hImage, XO, YO, SF, X + (W \ 2), Y, W - (W \ 2), H)
Else
DrawFractalRect(hImage, XO, YO, SF, X, Y, W, H \ 2)
DrawFractalRect(hImage, XO, YO, SF, X, Y + (H \ 2), W, H - (H \ 2))
Endif
Return
CALC_ALL:
XF = XF0
For I = X To X + W - 1
YF = YF0
For J = Y To Y + H - 1
ZX = 0
ZY = 0
For K = 0 To ITER_MAX - 1
T = ZX * ZX - ZY * ZY + XF
ZY = 2 * ZX * ZY + YF
If ((T * T) + (ZY * ZY)) > 4 Then Break
ZX = T
Next
If K < ITER_MAX Then hImage[I, J] = $aColor[K And 63]
YF += SF
Next
XF += SF
Next
Return
CALC_POINT:
ZX = 0
ZY = 0
For K = 0 To ITER_MAX - 1
T = ZX * ZX - ZY * ZY + XF
ZY = 2 * ZX * ZY + YF
If ((T * T) + (ZY * ZY)) > 4 Then Break
ZX = T
Next
If K < ITER_MAX Then
K = K And 63
C = $aColor[K]
If C <> CC Then bSame = False
hImage[I, J] = C
Else
C = 0
If C <> CC Then bSame = False
Endif
Return
End
' Public Sub FractalTask_Read(Data As String)
'
' Dim hTask As FractalTask = Last
' Print hTask.Index; ": "; Data
'
' End
'
' Public Sub FractalTask_Error(Data As String)
'
' Dim hTask As FractalTask = Last
' Print hTask.Index; "= "; Data
'
' End
Public Sub dwgFractal_Draw()
Dim hImage As Image
Dim X, Y, I, J As Float
Dim YT As Integer
X = $XC + (Draw.Clip.X - dwgFractal.W / 2) * $fScale
Y = $YC + (Draw.Clip.Y - dwgFractal.H / 2) * $fScale
Dim HT As Integer
hImage = New Image(Draw.Clip.W, Draw.Clip.H)
For I = 0 To hImage.W Step $hRose.W
@ -303,32 +62,50 @@ Public Sub dwgFractal_Draw()
Next
Next
If $bFast Then
FastDrawFractalRect(hImage, X, Y, $fScale, 0, 0, hImage.W, hImage.H)
Else
DrawFractalRect(hImage, X, Y, $fScale, 0, 0, hImage.W, hImage.H)
Endif
X = $XC + (Draw.Clip.X - dwgFractal.W / 2) * $fScale
Y = $YC + (Draw.Clip.Y - dwgFractal.H / 2) * $fScale
'Draw.Tile($hRose, 0, 0, dwgFractal.W, dwgFractal.H)
Draw.Image(hImage, Draw.Clip.X, Draw.Clip.Y)
'If $bFast Then
' FastDrawFractalRect(hImage, X, Y, $fScale, 0, 0, hImage.W, hImage.H)
' Draw.Image(hImage, Draw.Clip.X, Draw.Clip.Y)
'Else
Draw.Image(hImage, Draw.Clip.X, Draw.Clip.Y)
HT = hImage.H \ NTASK
For I = 0 To NTASK - 1
If $aResult[I] Then Draw.Image($aResult[I], Draw.Clip.X, Draw.Clip.Y + YT)
'RunTask(0, X, Y, 0, YT, hImage.W, HT)
'Y += HT * $fScale
YT += HT
Next
'RunTask(I, X, Y, 0, YT, hImage.W, hImage.H - HT)
'DrawFractalRect(hImage, X, Y, $fScale, 0, 0, hImage.W, hImage.H)
'Endif
YT = 8
Paint.Background = Color.SetAlpha(Color.White, 128)
Paint.Rectangle(4, 4, Draw.Font.Height * 26, Draw.Font.Height * 3 + 32)
Paint.Fill
YT = 12
If $bFast Then
Draw.Text(("Press F to deactivate Just-In-Time compilation"), 8, YT)
Draw.Text(("Press F to deactivate Just-In-Time compilation"), 12, YT)
Else
Draw.Text(("Press F to activate Just-In-Time compilation"), 8, YT)
Draw.Text(("Press F to activate Just-In-Time compilation"), 12, YT)
Endif
YT += Draw.Font.Height + 8
If $bRect Then
Draw.Text(("Press R to hide rectangle optimization"), 8, YT)
Draw.Text(("Press R to hide rectangle optimization"), 12, YT)
Else
Draw.Text(("Press R to show rectangle optimization"), 8, YT)
Draw.Text(("Press R to show rectangle optimization"), 12, YT)
Endif
YT += Draw.Font.Height + 8
Draw.Text(("Zoom") & ": " & CStr((Log2($fScale) + 6) * 8) & " " & ("Speed") & ": " & If($bFast, ("Fast"), ("Slow")) & " " & ("Max") & ": " & ITER_MAX, 8, YT)
Draw.Text(("Zoom") & ": " & CStr((Log2($fScale) + 6) * 8) & " " & ("Speed") & ": " & If($bFast, ("Fast"), ("Slow")) & " " & ("Max") & ": " & ITER_MAX & " " & ("Tasks") & ": " & NTASK, 12, YT)
End
@ -354,7 +131,8 @@ Public Sub dwgFractal_MouseWheel()
$XC -= $fScale * (Mouse.X - dwgFractal.W / 2)
$YC -= $fScale * (Mouse.Y - dwgFractal.H / 2)
Me.Refresh
If timRedraw.Enabled Then Return
timRedraw.Start
End
@ -384,22 +162,75 @@ Public Sub dwgFractal_MouseMove()
$XC = $XX + ($MX - Mouse.X) * $fScale
$YC = $YY + ($MY - Mouse.Y) * $fScale
Me.Refresh
If timRedraw.Enabled Then Return
timRedraw.Start
End
Public Sub dwgFractal_KeyPress()
If UCase(Key.Text) = "F" Then
$bFast = Not $bFast
Me.Refresh
If $bFast Then
FractalTask.FastDrawFractalRect(Null, 0, 0, 0, 0, 0, 0, 0)
Endif
Redraw(False)
Else If UCase(Key.Text) = "R" Then
$bRect = Not $bRect
Me.Refresh
Redraw(False)
Else If Key.Code = Key.Esc Then
Me.Close
Endif
End
Private Sub Redraw(bClear As Boolean)
Dim I As Integer
Dim XO As Float
Dim YO As Float
Dim HT As Integer
XO = $XC - (Me.ClientW / 2) * $fScale
YO = $YC - (Me.ClientH / 2) * $fScale
HT = Me.ClientH \ NTASK
For I = 0 To $aTask.Max
If $aTask[I] Then Try $aTask[I].Stop
If bClear Then $aResult[I] = Null
If I = $aTask.Max Then HT = Me.ClientH - HT * $aTask.Max
$aTask[I] = New FractalTask(XO, YO, $fScale, Me.ClientW, HT, ITER_MAX, $aColor, $bFast, $bRect) As "FractalTask"
$aTask[I].Index = I
YO += HT * $fScale
Next
dwgFractal.Refresh
End
Public Sub Form_Resize()
Redraw(True)
End
Public Sub timRedraw_Timer()
Dim I As Integer
For I = 0 To $aTask.Max
If $aTask[I].Running Then Return
Next
Redraw(False)
timRedraw.Stop
End

View file

@ -11,4 +11,8 @@
Focus = True
NoBackground = True
}
{ timRedraw #Timer
#MoveScaled(58,26)
Delay = 100
}
}

View file

@ -2,7 +2,7 @@ FFractal
Fractal
0
0
3.3.90
3.4.90
gb.image
gb.gui

View file

@ -44,6 +44,8 @@
#include "gbx_c_task.h"
//#define DEBUG_ME 1
DECLARE_EVENT(EVENT_Read);
DECLARE_EVENT(EVENT_Error);
DECLARE_EVENT(EVENT_Kill);
@ -332,11 +334,15 @@ static bool start_task(CTASK *_object)
if (ret->type != GB_T_VOID)
{
sprintf(buf, RETURN_FILE_PATTERN, getuid(), getppid(), getpid());
//fprintf(stderr, "serialize to: %s\n", buf);
#if DEBUG_ME
fprintf(stderr, "serialize to: %s\n", buf);
#endif
GB_ReturnConvVariant();
if (GB_Serialize(buf, ret))
{
//fprintf(stderr, "gb.task: serialization has failed\n");
#if DEBUG_ME
fprintf(stderr, "gb.task: serialization has failed\n");
#endif
exit(CHILD_RETURN);
}
}
@ -527,6 +533,9 @@ BEGIN_PROPERTY(Task_Value)
if (!THIS->child && THIS->stopped)
{
sprintf(path, RETURN_FILE_PATTERN, getuid(), getpid(), THIS->pid);
#if DEBUG_ME
fprintf(stderr,"unserialize from: %s\n", path);
#endif
if (WIFEXITED(THIS->status))
{

View file

@ -365,6 +365,43 @@ BEGIN_METHOD(Image_Blur, GB_INTEGER radius)
END_METHOD
BEGIN_PROPERTY(Image_Pixels)
GB_ARRAY array;
int size;
if (!GB_IMAGE_FMT_IS_32_BITS(THIS_IMAGE->format))
{
GB.Error("Image format must be 32 bits");
return;
}
size = THIS_IMAGE->width * THIS_IMAGE->height;
if (READ_PROPERTY)
{
GB.Array.New(&array, GB_T_INTEGER, size);
IMAGE_get_pixels(THIS_IMAGE, GB.Array.Get(array, 0));
GB.ReturnObject(array);
}
else
{
array = VPROP(GB_OBJECT);
if (GB.CheckObject(array))
return;
if (GB.Array.Count(array) < size)
{
GB.Error("Not enough pixels");
return;
}
IMAGE_set_pixels(THIS_IMAGE, GB.Array.Get(array, 0));
}
END_PROPERTY
GB_DESC CImageDesc[] =
{
GB_DECLARE("Image", sizeof(CIMAGE)),
@ -387,6 +424,7 @@ GB_DESC CImageDesc[] =
GB_PROPERTY_READ("Depth", "i", Image_Depth),
GB_PROPERTY_READ("Data", "p", Image_Data),
GB_PROPERTY("Format", "s", Image_Format),
GB_PROPERTY("Pixels", "Integer[]", Image_Pixels),
GB_METHOD("Clear", NULL, Image_Clear, NULL),
GB_METHOD("Fill", "Image", Image_Fill, "(Color)i"),

View file

@ -673,6 +673,13 @@ GB_COLOR IMAGE_get_pixel(GB_IMG *img, int x, int y)
return GB_COLOR_from_format(col, img->format);
}
void IMAGE_get_pixels(GB_IMG *img, int *data)
{
SYNCHRONIZE(img);
memcpy(data, img->data, img->width * img->height * sizeof(int));
}
void IMAGE_set_pixel(GB_IMG *img, int x, int y, GB_COLOR col)
{
if (!is_valid(img, x, y))
@ -683,6 +690,13 @@ void IMAGE_set_pixel(GB_IMG *img, int x, int y, GB_COLOR col)
MODIFY(img);
}
void IMAGE_set_pixels(GB_IMG *img, int *data)
{
SYNCHRONIZE(img);
memcpy(img->data, data, img->width * img->height * sizeof(int));
MODIFY(img);
}
void IMAGE_fill_rect(GB_IMG *img, int x, int y, int w, int h, GB_COLOR col, bool opaque)
{
uint *p;

View file

@ -39,22 +39,36 @@ static inline uint RGBA(int r, int g, int b, int a) { return ((a & 0xff) << 24)
static inline int GRAY(uint rgba) { return (RED(rgba) * 11 + GREEN(rgba) * 16 + BLUE(rgba) * 5) / 32; }
int IMAGE_size(GB_IMG *img);
void IMAGE_create(GB_IMG *img, int width, int height, int format);
void IMAGE_create_with_data(GB_IMG *img, int width, int height, int format, unsigned char *data);
void IMAGE_take(GB_IMG *img, GB_IMG_OWNER *owner, void *owner_handle, int width, int height, unsigned char *data);
void *IMAGE_check(GB_IMG *img, GB_IMG_OWNER *temp_owner);
void IMAGE_synchronize(GB_IMG *img);
void IMAGE_delete(GB_IMG *img);
void IMAGE_convert(GB_IMG *img, int format);
void IMAGE_fill(GB_IMG *img, GB_COLOR col);
void IMAGE_fill_rect(GB_IMG *img, int x, int y, int w, int h, GB_COLOR col, bool opaque);
void IMAGE_make_gray(GB_IMG *img);
void IMAGE_make_transparent(GB_IMG *img, GB_COLOR color);
GB_COLOR IMAGE_get_pixel(GB_IMG *img, int x, int y);
void IMAGE_set_pixel(GB_IMG *img, int x, int y, GB_COLOR col);
void IMAGE_get_pixels(GB_IMG *img, int *data);
void IMAGE_set_pixels(GB_IMG *img, int *data);
void IMAGE_replace(GB_IMG *img, GB_COLOR src, GB_COLOR dst, bool noteq);
void IMAGE_set_default_format(int format);
int IMAGE_get_default_format();
const char *IMAGE_format_to_string(int fmt);
void IMAGE_bitblt(GB_IMG *dst, int dx, int dy, int dw, int dh, GB_IMG *src, int sx, int sy, int sw, int sh);
void IMAGE_draw_alpha(GB_IMG *dst, int dx, int dy, GB_IMG *src, int sx, int sy, int sw, int sh);
void IMAGE_compose(GB_IMG *dst, int dx, int dy, int dw, int dh, GB_IMG *src, int sx, int sy, int sw, int sh);
@ -63,7 +77,6 @@ void IMAGE_mask(GB_IMG *img, GB_COLOR color);
void IMAGE_mirror(GB_IMG *src, GB_IMG *dst, bool horizontal, bool vertical);
void IMAGE_rotate(GB_IMG *src, GB_IMG *dst, bool left);
void IMAGE_transform(GB_IMG *dst, GB_IMG *src, double sx, double sy, double sdx, double sdy);
const char *IMAGE_format_to_string(int fmt);
void IMAGE_set_opacity(GB_IMG *dst, uchar opacity);
void IMAGE_blur(GB_IMG *img, int radius);