From b6e3adf1777f5b50908c50b1ffd950a41634e54e Mon Sep 17 00:00:00 2001 From: ronaldhordijk Date: Sat, 3 Sep 2005 11:22:04 +0000 Subject: [PATCH] Create transparent images And moved to one unit --- 2.10/Source/Render.pas | 40 ++-- 2.10/Source/Render64.pas | 369 +++++--------------------------- 2.10/Source/RenderMM.pas | 302 +++----------------------- 2.10/Source/RenderThread.pas | 37 +++- 2.10/Source/ScriptRender.pas | 13 +- 2.10/Source/formPostProcess.pas | 12 +- 6 files changed, 145 insertions(+), 628 deletions(-) diff --git a/2.10/Source/Render.pas b/2.10/Source/Render.pas index 48bd404..9edbb18 100644 --- a/2.10/Source/Render.pas +++ b/2.10/Source/Render.pas @@ -45,7 +45,7 @@ type end; PBucket = ^TBucket; TBucketArray = array of TBucket; - + PBucketArray = ^PBucketArray; type TBaseRenderer = class @@ -67,10 +67,13 @@ type destructor Destroy; override; procedure SetCP(CP: TControlPoint); - function GetImage: TBitmap; virtual; abstract; procedure Render; virtual; abstract; + + function GetImage: TBitmap; virtual; abstract; procedure UpdateImage(CP: TControlPoint); virtual; - procedure Stop; + procedure SaveImage(const FileName: String); virtual; + + procedure Stop; virtual; property OnProgress: TOnProgress read FOnProgress @@ -107,10 +110,12 @@ type destructor Destroy; override; procedure SetCP(CP: TControlPoint); - function GetImage: TBitmap; procedure Render; procedure RenderMaxMem(MaxMem: Int64); + + function GetImage: TBitmap; procedure UpdateImage(CP: TControlPoint); + procedure SaveImage(const FileName: String); procedure Stop; @@ -223,6 +228,24 @@ begin end; /////////////////////////////////////////////////////////////////////////////// +procedure TRenderer.RenderMaxMem(MaxMem: Int64); +begin + FMaxMem := MaxMem; + Render; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderer.UpdateImage(CP: TControlPoint); +begin + +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderer.SaveImage(const FileName: String); +begin + if assigned(FRenderer) then + FRenderer.SaveImage(FileName); +end; { TBaseRenderer } @@ -291,14 +314,7 @@ begin end; /////////////////////////////////////////////////////////////////////////////// -procedure TRenderer.RenderMaxMem(MaxMem: Int64); -begin - FMaxMem := MaxMem; - Render; -end; - -/////////////////////////////////////////////////////////////////////////////// -procedure TRenderer.UpdateImage(CP: TControlPoint); +procedure TBaseRenderer.SaveImage(const FileName: String); begin end; diff --git a/2.10/Source/Render64.pas b/2.10/Source/Render64.pas index c3bd4f6..82df848 100644 --- a/2.10/Source/Render64.pas +++ b/2.10/Source/Render64.pas @@ -21,42 +21,14 @@ unit Render64; interface uses - Windows, Graphics, + Windows, Graphics, ImageMaker, Render, Controlpoint; -type - TOnProgress = procedure(prog: double) of object; - -type - TColorMapColor = Record - Red : Int64; - Green: Int64; - Blue : Int64; -// Count: Integer; - end; - PColorMapColor = ^TColorMapColor; - TColorMapArray = array[0..255] of TColorMapColor; - - TBucket = Record - Red : Int64; - Green: Int64; - Blue : Int64; - Count: Int64; - end; - PBucket = ^TBucket; - TBucketArray = array of TBucket; - type TRenderer64 = class(TBaseRenderer) private - bm: TBitmap; - oversample: Int64; - filter_width: Integer; - filter: array of array of extended; - image_Width: Integer; - image_Height: Integer; BucketWidth: Int64; BucketHeight: Int64; BucketSize: Int64; @@ -68,21 +40,14 @@ type Buckets: TBucketArray; ColorMap: TColorMapArray; - bg: array[0..2] of extended; -// vib_gam_n: Integer; -// vibrancy: double; - gamma: double; - bounds: array[0..3] of extended; size: array[0..1] of extended; ppux, ppuy: extended; - - procedure CreateFilter; - procedure NormalizeFilter; + FImageMaker: TImageMaker; procedure InitValues; procedure InitBuffers; - procedure InitBitmap(w: Integer = 0; h: Integer = 0); + procedure ClearBuffers; procedure ClearBuckets; procedure CreateColorMap; @@ -92,17 +57,15 @@ type procedure AddPointsToBucketsAngle(const points: TPointsArray); overload; procedure SetPixels; - procedure CreateBMFromBuckets(YOffset: Integer = 0); - public constructor Create; override; destructor Destroy; override; - function GetImage: TBitmap; override; - procedure Render; override; + function GetImage: TBitmap; override; procedure UpdateImage(CP: TControlPoint); override; + procedure SaveImage(const FileName: String); override; end; implementation @@ -112,6 +75,23 @@ uses { TRenderer64 } +/////////////////////////////////////////////////////////////////////////////// +constructor TRenderer64.Create; +begin + inherited Create; + + FImageMaker := TImageMaker.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +destructor TRenderer64.Destroy; +begin + FImageMaker.Free; + + inherited; +end; + + /////////////////////////////////////////////////////////////////////////////// procedure TRenderer64.ClearBuckets; var @@ -151,12 +131,12 @@ begin t1 := (gutter_width) / (oversample * ppuy); t2 := (2 * max_gutter_width - gutter_width) / (oversample * ppux); t3 := (2 * max_gutter_width - gutter_width) / (oversample * ppuy); - corner0 := fcp.center[0] - image_width / ppux / 2.0; - corner1 := fcp.center[1] - image_height / ppuy / 2.0; + corner0 := fcp.center[0] - fcp.Width / ppux / 2.0; + corner1 := fcp.center[1] - fcp.Height / ppuy / 2.0; bounds[0] := corner0 - t0; bounds[1] := corner1 - t1 + shift; - bounds[2] := corner0 + image_width / ppux + t2; - bounds[3] := corner1 + image_height / ppuy + t3; //+ shift; + bounds[2] := corner0 + fcp.Width / ppux + t2; + bounds[3] := corner1 + fcp.Height / ppuy + t3; //+ shift; if abs(bounds[2] - bounds[0]) > 0.01 then size[0] := 1.0 / (bounds[2] - bounds[0]) else @@ -189,53 +169,10 @@ begin {$ENDIF} end; -/////////////////////////////////////////////////////////////////////////////// -procedure TRenderer64.CreateFilter; -var - i, j: integer; - fw: integer; - adjust: double; - ii, jj: double; -begin - oversample := fcp.spatial_oversample; - fw := Trunc(2.0 * FILTER_CUTOFF * oversample * fcp.spatial_filter_radius); - filter_width := fw + 1; - - // make sure it has same parity as oversample - if odd(filter_width + oversample) then - inc(filter_width); - - if (fw > 0.0) then - adjust := (1.0 * FILTER_CUTOFF * filter_width) / fw - else - adjust := 1.0; - - setLength(filter, filter_width, filter_width); - for i := 0 to filter_width - 1 do begin - for j := 0 to filter_width - 1 do begin - ii := ((2.0 * i + 1.0)/ filter_width - 1.0) * adjust; - jj := ((2.0 * j + 1.0)/ filter_width - 1.0) * adjust; - - filter[i, j] := exp(-2.0 * (ii * ii + jj * jj)); - end; - end; - - Normalizefilter; -end; - -/////////////////////////////////////////////////////////////////////////////// -destructor TRenderer64.Destroy; -begin - if assigned(bm) then - bm.Free; - - inherited; -end; - /////////////////////////////////////////////////////////////////////////////// function TRenderer64.GetImage: TBitmap; begin - Result := bm; + Result := FImageMaker.GetImage; end; /////////////////////////////////////////////////////////////////////////////// @@ -243,52 +180,28 @@ procedure TRenderer64.InitBuffers; const MaxFilterWidth = 25; begin + oversample := fcp.spatial_oversample; max_gutter_width := (MaxFilterWidth - oversample) div 2; - gutter_width := (filter_width - oversample) div 2; - BucketHeight := oversample * image_height + 2 * max_gutter_width; - Bucketwidth := oversample * image_width + 2 * max_gutter_width; + gutter_width := (FImageMaker.GetFilterSize - oversample) div 2; + BucketHeight := oversample * fcp.Height + 2 * max_gutter_width; + Bucketwidth := oversample * fcp.Width + 2 * max_gutter_width; BucketSize := BucketWidth * BucketHeight; if high(buckets) <> (BucketSize - 1) then begin SetLength(buckets, BucketSize); end; + + // share the buffer with imagemaker + FImageMaker.SetBucketData(Buckets, BucketWidth); end; /////////////////////////////////////////////////////////////////////////////// procedure TRenderer64.InitValues; begin - image_height := fcp.Height; - image_Width := fcp.Width; - - CreateFilter; InitBuffers; CreateCamera; - CreateColorMap; - -// vibrancy := 0; - gamma := 0; -// vib_gam_n := 0; - bg[0] := 0; - bg[1] := 0; - bg[2] := 0; -end; - -/////////////////////////////////////////////////////////////////////////////// -procedure TRenderer64.NormalizeFilter; -var - i, j: integer; - t: double; -begin - t := 0; - for i := 0 to filter_width - 1 do - for j := 0 to filter_width - 1 do - t := t + filter[i, j]; - - for i := 0 to filter_width - 1 do - for j := 0 to filter_width - 1 do - filter[i, j] := filter[i, j] / t; end; /////////////////////////////////////////////////////////////////////////////// @@ -299,8 +212,6 @@ var bws, bhs: double; bx, by: double; wx, wy: double; -// R: double; -// V1, v2, v3: integer; Bucket: PBucket; MapColor: PColorMapColor; begin @@ -342,8 +253,6 @@ var bws, bhs: double; bx, by: double; wx, wy: double; -// R: double; -// V1, v2, v3: integer; Bucket: PBucket; MapColor: PColorMapColor; begin @@ -388,11 +297,10 @@ end; /////////////////////////////////////////////////////////////////////////////// procedure TRenderer64.SetPixels; var - i{,j}: integer; + i: integer; nsamples: Int64; nrbatches: Integer; points: TPointsArray; -// f: text; begin // if FileExists('c:\temp\flame.txt') then // Deletefile('c:\temp\flame.txt'); @@ -442,201 +350,22 @@ begin Progress(1); end; -/////////////////////////////////////////////////////////////////////////////// -procedure TRenderer64.CreateBMFromBuckets(YOffset: Integer); -var - i, j: integer; - - alpha: double; -// r,g,b: double; - ai, ri, gi, bi: Integer; - bgtot: Integer; - ls: double; - ii, jj: integer; - fp: array[0..3] of double; - Row: PLongintArray; - vib, notvib: Integer; - bgi: array[0..2] of Integer; - bucketpos: Integer; - filterValue: double; - filterpos: Integer; - lsa: array[0..1024] of double; -var - k1, k2: double; - area: double; -begin - if fcp.gamma = 0 then - gamma := fcp.gamma - else - gamma := 1 / fcp.gamma; - vib := round(fcp.vibrancy * 256.0); - notvib := 256 - vib; - - bgi[0] := round(fcp.background[0]); - bgi[1] := round(fcp.background[1]); - bgi[2] := round(fcp.background[2]); - bgtot := RGB(bgi[2], bgi[1], bgi[0]); - - k1 := (fcp.Contrast * BRIGHT_ADJUST * fcp.brightness * 268 * PREFILTER_WHITE) / 256.0; - area := image_width * image_height / (ppux * ppuy); - k2 := (oversample * oversample) / (fcp.Contrast * area * fcp.White_level * sample_density); - - lsa[0] := 0; - for i := 1 to 1024 do begin - lsa[i] := (k1 * log10(1 + fcp.White_level * i * k2)) / (fcp.White_level * i); - end; -(* - if filter_width > 1 then begin - for i := 0 to BucketWidth * BucketHeight - 1 do begin - if Buckets[i].count = 0 then - Continue; - - ls := lsa[Min(1023, Buckets[i].Count)]; - - Buckets[i].Red := Round(Buckets[i].Red * ls); - Buckets[i].Green := Round(Buckets[i].Green * ls); - Buckets[i].Blue := Round(Buckets[i].Blue * ls); - Buckets[i].Count := Round(Buckets[i].Count * ls); - end; - end; -*) - bm.PixelFormat := pf32bit; - - ls := 0; - ai := 0; - bucketpos := 0; - for i := 0 to Image_Height - 1 do begin - if FStop then - Break; - - Progress(i / Image_Height); - - Row := PLongintArray(bm.scanline[YOffset + i]); - for j := 0 to Image_Width - 1 do begin - if filter_width > 1 then begin - fp[0] := 0; - fp[1] := 0; - fp[2] := 0; - fp[3] := 0; - - for ii := 0 to filter_width - 1 do begin - for jj := 0 to filter_width - 1 do begin - filterValue := filter[ii, jj]; - filterpos := bucketpos + ii * BucketWidth + jj; - - ls := lsa[Min(1023, Buckets[filterpos].Count)]; - - fp[0] := fp[0] + filterValue * ls * Buckets[filterpos].Red; - fp[1] := fp[1] + filterValue * ls * Buckets[filterpos].Green; - fp[2] := fp[2] + filterValue * ls * Buckets[filterpos].Blue; - fp[3] := fp[3] + filterValue * ls * Buckets[filterpos].Count; - end; - end; - - fp[0] := fp[0] / PREFILTER_WHITE; - fp[1] := fp[1] / PREFILTER_WHITE; - fp[2] := fp[2] / PREFILTER_WHITE; - fp[3] := fcp.white_level * fp[3] / PREFILTER_WHITE; - end else begin - ls := lsa[Min(1023, Buckets[bucketpos].count)] / PREFILTER_WHITE; - - fp[0] := ls * Buckets[bucketpos].Red; - fp[1] := ls * Buckets[bucketpos].Green; - fp[2] := ls * Buckets[bucketpos].Blue; - fp[3] := ls * Buckets[bucketpos].Count * fcp.white_level; - end; - - Inc(bucketpos, oversample); - - if (fp[3] > 0.0) then begin - alpha := power(fp[3], gamma); - ls := vib * alpha / fp[3]; - ai := round(alpha * 256); - if (ai < 0) then - ai := 0 - else if (ai > 256) then - ai := 256; - ai := 256 - ai; - end else begin - // no intensity so simply set the BG; - Row[j] := bgtot; - continue; - end; - - if (notvib > 0) then - ri := Round(ls * fp[0] + notvib * power(fp[0], gamma)) - else - ri := Round(ls * fp[0]); - ri := ri + (ai * bgi[0]) shr 8; - if (ri < 0) then - ri := 0 - else if (ri > 255) then - ri := 255; - - if (notvib > 0) then - gi := Round(ls * fp[1] + notvib * power(fp[1], gamma)) - else - gi := Round(ls * fp[1]); - gi := gi + (ai * bgi[1]) shr 8; - if (gi < 0) then - gi := 0 - else if (gi > 255) then - gi := 255; - - if (notvib > 0) then - bi := Round(ls * fp[2] + notvib * power(fp[2], gamma)) - else - bi := Round(ls * fp[2]); - bi := bi + (ai * bgi[2]) shr 8; - if (bi < 0) then - bi := 0 - else if (bi > 255) then - bi := 255; - - Row[j] := RGB(bi, gi, ri);// + (ai shl 24); - end; - - Inc(bucketpos, 2 * max_gutter_width); - Inc(bucketpos, (oversample - 1) * BucketWidth); - end; - bm.PixelFormat := pf24bit; - - Progress(1); -end; - -/////////////////////////////////////////////////////////////////////////////// -procedure TRenderer64.InitBitmap(w, h: Integer); -begin - if not Assigned(bm) then - bm := TBitmap.Create; - - bm.PixelFormat := pf32bit; - - if (w <> 0) and (h <> 0) then begin - bm.Width := w; - bm.Height := h; - end else begin - bm.Width := image_Width; - bm.Height := image_Height; - end; -end; - -/////////////////////////////////////////////////////////////////////////////// -constructor TRenderer64.Create; -begin - inherited Create; -end; - /////////////////////////////////////////////////////////////////////////////// procedure TRenderer64.Render; begin FStop := False; + FImageMaker.SetCP(FCP); + FImageMaker.Init; InitValues; - InitBitmap; + ClearBuffers; SetPixels; - CreateBMFromBuckets; + + if not FStop then begin + FImageMaker.OnProgress := OnProgress; + FImageMaker.CreateImage; + end; end; /////////////////////////////////////////////////////////////////////////////// @@ -649,9 +378,17 @@ begin FCP.contrast := cp.contrast; FCP.brightness := cp.brightness; - CreateFilter; + FImageMaker.SetCP(FCP); + FImageMaker.Init; - CreateBMFromBuckets; + FImageMaker.OnProgress := OnProgress; + FImageMaker.CreateImage; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TRenderer64.SaveImage(const FileName: String); +begin + FImageMaker.SaveImage(FileName); end; /////////////////////////////////////////////////////////////////////////////// diff --git a/2.10/Source/RenderMM.pas b/2.10/Source/RenderMM.pas index cbc2571..fc95481 100644 --- a/2.10/Source/RenderMM.pas +++ b/2.10/Source/RenderMM.pas @@ -22,35 +22,11 @@ interface uses Windows, Graphics, - Render, Controlpoint; - -type - TOnProgress = procedure(prog: double) of object; - -type - TColorMapColor = Record - Red : Int64; - Green: Int64; - Blue : Int64; -// Count: Integer; - end; - PColorMapColor = ^TColorMapColor; - TColorMapArray = array[0..255] of TColorMapColor; - - TBucket = Record - Red : Int64; - Green: Int64; - Blue : Int64; - Count: Int64; - end; - PBucket = ^TBucket; - TBucketArray = array of TBucket; + Render, Controlpoint, ImageMaker; type TRendererMM64 = class(TBaseRenderer) private - bm: TBitmap; - oversample: Integer; filter_width: Integer; filter: array of array of extended; @@ -67,24 +43,16 @@ type Buckets: TBucketArray; ColorMap: TColorMapArray; - bg: array[0..2] of extended; - vib_gam_n: Integer; - vibrancy: double; - gamma: double; - bounds: array[0..3] of extended; size: array[0..1] of extended; FRotationCenter: array[0..1] of extended; ppux, ppuy: extended; nrSlices: int64; Slice: int64; - - procedure CreateFilter; - procedure NormalizeFilter; + FImageMaker: TImageMaker; procedure InitValues; procedure InitBuffers; - procedure InitBitmap(w: Integer = 0; h: Integer = 0); procedure ClearBuffers; procedure ClearBuckets; procedure CreateColorMap; @@ -94,8 +62,6 @@ type procedure AddPointsToBucketsAngle(const points: TPointsArray); overload; procedure SetPixels; - procedure CreateBMFromBuckets(YOffset: Integer = 0); - protected function GetSlice: integer; override; function GetNrSlices: integer; override; @@ -105,6 +71,7 @@ type destructor Destroy; override; function GetImage: TBitmap; override; + procedure SaveImage(const FileName: String); override; procedure Render; override; @@ -181,45 +148,10 @@ begin end; end; -/////////////////////////////////////////////////////////////////////////////// -procedure TRendererMM64.CreateFilter; -var - i, j: integer; - fw: integer; - adjust: double; - ii, jj: double; -begin - oversample := fcp.spatial_oversample; - fw := Trunc(2.0 * FILTER_CUTOFF * oversample * fcp.spatial_filter_radius); - filter_width := fw + 1; - - // make sure it has same parity as oversample - if odd(filter_width + oversample) then - inc(filter_width); - - if (fw > 0.0) then - adjust := (1.0 * FILTER_CUTOFF * filter_width) / fw - else - adjust := 1.0; - - setLength(filter, filter_width, filter_width); - for i := 0 to filter_width - 1 do begin - for j := 0 to filter_width - 1 do begin - ii := ((2.0 * i + 1.0)/ filter_width - 1.0) * adjust; - jj := ((2.0 * j + 1.0)/ filter_width - 1.0) * adjust; - - filter[i, j] := exp(-2.0 * (ii * ii + jj * jj)); - end; - end; - - Normalizefilter; -end; - /////////////////////////////////////////////////////////////////////////////// destructor TRendererMM64.Destroy; begin - if assigned(bm) then - bm.Free; + FImageMaker.Free; inherited; end; @@ -227,13 +159,14 @@ end; /////////////////////////////////////////////////////////////////////////////// function TRendererMM64.GetImage: TBitmap; begin - Result := bm; + Result := FImageMaker.GetImage; end; /////////////////////////////////////////////////////////////////////////////// procedure TRendererMM64.InitBuffers; begin - gutter_width := (filter_width - oversample) div 2; + oversample := fcp.spatial_oversample; + gutter_width := (FImageMaker.GetFilterSize - oversample) div 2; BucketHeight := oversample * image_height + 2 * gutter_width; Bucketwidth := oversample * image_width + 2 * gutter_width; BucketSize := BucketWidth * BucketHeight; @@ -241,6 +174,9 @@ begin if high(buckets) <> (BucketSize - 1) then begin SetLength(buckets, BucketSize); end; + + // share the buffer with imagemaker + FImageMaker.SetBucketData(Buckets, BucketWidth); end; /////////////////////////////////////////////////////////////////////////////// @@ -249,35 +185,11 @@ begin image_height := fcp.Height; image_Width := fcp.Width; - CreateFilter; CreateCamera; InitBuffers; CreateColorMap; - - vibrancy := 0; - gamma := 0; - vib_gam_n := 0; - bg[0] := 0; - bg[1] := 0; - bg[2] := 0; -end; - -/////////////////////////////////////////////////////////////////////////////// -procedure TRendererMM64.NormalizeFilter; -var - i, j: integer; - t: double; -begin - t := 0; - for i := 0 to filter_width - 1 do - for j := 0 to filter_width - 1 do - t := t + filter[i, j]; - - for i := 0 to filter_width - 1 do - for j := 0 to filter_width - 1 do - filter[i, j] := filter[i, j] / t; end; /////////////////////////////////////////////////////////////////////////////// @@ -413,183 +325,13 @@ begin Progress(1); end; -/////////////////////////////////////////////////////////////////////////////// -procedure TRendererMM64.CreateBMFromBuckets(YOffset: Integer); -var - i, j: integer; - alpha: double; -// r,g,b: double; - ai, ri, gi, bi: Integer; - bgtot: Integer; - ls: double; - ii, jj: integer; - fp: array[0..3] of double; - Row: PLongintArray; - vib, notvib: Integer; - bgi: array[0..2] of Integer; - bucketpos: Integer; - filterValue: double; - filterpos: Integer; - lsa: array[0..1024] of double; -var - k1, k2: double; - area: double; -begin - if fcp.gamma = 0 then - gamma := fcp.gamma - else - gamma := 1 / fcp.gamma; - vib := round(fcp.vibrancy * 256.0); - notvib := 256 - vib; - - bgi[0] := round(fcp.background[0]); - bgi[1] := round(fcp.background[1]); - bgi[2] := round(fcp.background[2]); - bgtot := RGB(bgi[2], bgi[1], bgi[0]); - - k1 := (fcp.Contrast * BRIGHT_ADJUST * fcp.brightness * 268 * PREFILTER_WHITE) / 256.0; - area := image_width * image_height / (ppux * ppuy); - k2 := (oversample * oversample) / (fcp.Contrast * area * fcp.White_level * sample_density); - - lsa[0] := 0; - for i := 1 to 1024 do begin - lsa[i] := (k1 * log10(1 + fcp.White_level * i * k2)) / (fcp.White_level * i); - end; - - if filter_width > 1 then begin - for i := 0 to BucketWidth * BucketHeight - 1 do begin - if Buckets[i].count = 0 then - Continue; - - ls := lsa[Min(1023, Buckets[i].Count)]; - - Buckets[i].Red := Round(Buckets[i].Red * ls); - Buckets[i].Green := Round(Buckets[i].Green * ls); - Buckets[i].Blue := Round(Buckets[i].Blue * ls); - Buckets[i].Count := Round(Buckets[i].Count * ls); - end; - end; - - ls := 0; - ai := 0; - bucketpos := 0; - for i := 0 to Image_Height - 1 do begin - if FStop then - Break; - - Progress(i / Image_Height); - - Row := PLongintArray(bm.scanline[YOffset + i]); - for j := 0 to Image_Width - 1 do begin - if filter_width > 1 then begin - fp[0] := 0; - fp[1] := 0; - fp[2] := 0; - fp[3] := 0; - - for ii := 0 to filter_width - 1 do begin - for jj := 0 to filter_width - 1 do begin - filterValue := filter[ii, jj]; - filterpos := bucketpos + ii * BucketWidth + jj; - - fp[0] := fp[0] + filterValue * Buckets[filterpos].Red; - fp[1] := fp[1] + filterValue * Buckets[filterpos].Green; - fp[2] := fp[2] + filterValue * Buckets[filterpos].Blue; - fp[3] := fp[3] + filterValue * Buckets[filterpos].Count; - end; - end; - - fp[0] := fp[0] / PREFILTER_WHITE; - fp[1] := fp[1] / PREFILTER_WHITE; - fp[2] := fp[2] / PREFILTER_WHITE; - fp[3] := fcp.white_level * fp[3] / PREFILTER_WHITE; - end else begin - ls := lsa[Min(1023, Buckets[bucketpos].count)] / PREFILTER_WHITE; - - fp[0] := ls * Buckets[bucketpos].Red; - fp[1] := ls * Buckets[bucketpos].Green; - fp[2] := ls * Buckets[bucketpos].Blue; - fp[3] := ls * Buckets[bucketpos].Count * fcp.white_level; - end; - - Inc(bucketpos, oversample); - - if (fp[3] > 0.0) then begin - alpha := power(fp[3], gamma); - ls := vib * alpha / fp[3]; - ai := round(alpha * 256); - if (ai < 0) then - ai := 0 - else if (ai > 256) then - ai := 256; - ai := 256 - ai; - end else begin - // no intensity so simply set the BG; - Row[j] := bgtot; - continue; - end; - - if (notvib > 0) then - ri := Round(ls * fp[0] + notvib * power(fp[0], gamma)) - else - ri := Round(ls * fp[0]); - ri := ri + (ai * bgi[0]) shr 8; - if (ri < 0) then - ri := 0 - else if (ri > 255) then - ri := 255; - - if (notvib > 0) then - gi := Round(ls * fp[1] + notvib * power(fp[1], gamma)) - else - gi := Round(ls * fp[1]); - gi := gi + (ai * bgi[1]) shr 8; - if (gi < 0) then - gi := 0 - else if (gi > 255) then - gi := 255; - - if (notvib > 0) then - bi := Round(ls * fp[2] + notvib * power(fp[2], gamma)) - else - bi := Round(ls * fp[2]); - bi := bi + (ai * bgi[2]) shr 8; - if (bi < 0) then - bi := 0 - else if (bi > 255) then - bi := 255; - - Row[j] := RGB(bi, gi, ri); - end; - - Inc(bucketpos, 2 * gutter_width); - Inc(bucketpos, (oversample - 1) * BucketWidth); - end; - - Progress(1); -end; - -/////////////////////////////////////////////////////////////////////////////// -procedure TRendererMM64.InitBitmap(w, h: Integer); -begin - if not Assigned(bm) then - bm := TBitmap.Create; - - bm.PixelFormat := pf32bit; - - if (w <> 0) and (h <> 0) then begin - bm.Width := w; - bm.Height := h; - end else begin - bm.Width := image_Width; - bm.Height := image_Height; - end; -end; /////////////////////////////////////////////////////////////////////////////// constructor TRendererMM64.Create; begin inherited Create; + + FImageMaker := TImageMaker.Create; end; /////////////////////////////////////////////////////////////////////////////// @@ -638,6 +380,9 @@ begin end; end; + FImageMaker.SetCP(FCP); + FImageMaker.Init; + fcp.sample_density := fcp.sample_density * nrslices; fcp.height := fcp.height div nrslices; center_y := fcp.center[1]; @@ -645,17 +390,22 @@ begin center_base := center_y - ((nrslices - 1) * fcp.height) / (2 * fcp.pixels_per_unit * zoom_scale); InitValues; - InitBitmap(fcp.Width, NrSlices * fcp.Height); for i := 0 to NrSlices - 1 do begin + if FStop then + Exit; + Slice := i; fcp.center[1] := center_base + fcp.height * slice / (fcp.pixels_per_unit * zoom_scale); CreateCamera; ClearBuffers; SetPixels; - CreateBMFromBuckets(Slice * fcp.height); + + if not FStop then begin + FImageMaker.OnProgress := OnProgress; + FImageMaker.CreateImage(Slice * fcp.height); + end; end; - bm.PixelFormat := pf24bit; fcp.sample_density := fcp.sample_density / nrslices; fcp.height := fcp.height * nrslices; @@ -673,6 +423,12 @@ begin Result := NrSlices; end; +/////////////////////////////////////////////////////////////////////////////// +procedure TRendererMM64.SaveImage(const FileName: String); +begin + FImageMaker.SaveImage(FileName); +end; + /////////////////////////////////////////////////////////////////////////////// end. diff --git a/2.10/Source/RenderThread.pas b/2.10/Source/RenderThread.pas index 1340745..2eebe27 100644 --- a/2.10/Source/RenderThread.pas +++ b/2.10/Source/RenderThread.pas @@ -22,7 +22,7 @@ interface uses Classes, windows, Messages, Graphics, - controlPoint, Render, Render32, Render64, RenderMM; + controlPoint, Render, Render64, Render64MT, RenderMM; const WM_THREAD_COMPLETE = WM_APP + 5437; @@ -37,12 +37,14 @@ type FCP: TControlPoint; Fcompatibility: Integer; FMaxMem: int64; + FNrThreads: Integer; procedure Render; function GetNrSlices: integer; function GetSlice: integer; procedure Setcompatibility(const Value: Integer); procedure SetMaxMem(const Value: int64); + procedure SetNrThreads(const Value: Integer); public TargetHandle: HWND; @@ -50,15 +52,17 @@ type destructor Destroy; override; procedure SetCP(CP: TControlPoint); - function GetImage: TBitmap; + function GetImage: TBitmap; + procedure SaveImage(const FileName: String); + procedure Execute; override; - function GetRenderer: TBaseRenderer; + function GetRenderer: TBaseRenderer; procedure Terminate; property OnProgress: TOnProgress - read FOnProgress - write FOnProgress; + read FOnProgress + write FOnProgress; property Slice: integer read GetSlice; @@ -70,6 +74,9 @@ type property compatibility: Integer read Fcompatibility write Setcompatibility; + property NrThreads: Integer + read FNrThreads + write SetNrThreads; end; implementation @@ -118,7 +125,12 @@ begin FRenderer.Free; if MaxMem = 0 then begin - FRenderer := TRenderer64.Create; + if NrThreads <= 1 then begin + FRenderer := TRenderer64.Create; + end else begin + FRenderer := TRenderer64MT.Create; + TRenderer64MT(FRenderer).NrOfTreads := NrThreads; + end; end else begin FRenderer := TRendererMM64.Create; FRenderer.MaxMem := MaxMem @@ -187,5 +199,18 @@ begin FRenderer := nil; end; +///////////////////////////////////////////////////////////////////////////////end. +procedure TRenderThread.SetNrThreads(const Value: Integer); +begin + FNrThreads := Value; +end; + +///////////////////////////////////////////////////////////////////////////////end. +procedure TRenderThread.SaveImage(const FileName: String); +begin + if assigned(FRenderer) then + FRenderer.SaveImage(FileName); +end; + ///////////////////////////////////////////////////////////////////////////////end. end. diff --git a/2.10/Source/ScriptRender.pas b/2.10/Source/ScriptRender.pas index dcc30e1..1327b3c 100644 --- a/2.10/Source/ScriptRender.pas +++ b/2.10/Source/ScriptRender.pas @@ -21,8 +21,7 @@ interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - ComCtrls, StdCtrls, Render, cmap, ControlPoint, ImageDLLLoader, - PNGLoader, BMPLoader, LinarBitmap, ExtCtrls, FileUtils, JPEGLoader, JPEG; + ComCtrls, StdCtrls, Render, cmap, ControlPoint; const WM_THREAD_COMPLETE = WM_APP + 5437; @@ -91,14 +90,7 @@ begin if (ScriptEditor.Renderer.MaxMemory > 0) then Renderer.RenderMaxMem(ScriptEditor.Renderer.MaxMemory) else Renderer.Render; - with TLinearBitmap.Create do - try - Assign(Renderer.GetImage); - JPEGLoader.Default.Quality := JPEGQuality; - if not cancelled then SaveToFile(FileName); - finally - Free; - end; + Renderer.SaveImage(FileName); ScriptEditor.Scripter.Paused := False; end; @@ -124,7 +116,6 @@ procedure TScriptRenderForm.FormCreate(Sender: TObject); begin Renderer := TRenderer.Create; cp := TControlPoint.Create; - ImageDLLLoader.Default.FindDLLs(ProgramPath); end; procedure TScriptRenderForm.btnCancelClick(Sender: TObject); diff --git a/2.10/Source/formPostProcess.pas b/2.10/Source/formPostProcess.pas index b885da2..69573e2 100644 --- a/2.10/Source/formPostProcess.pas +++ b/2.10/Source/formPostProcess.pas @@ -56,8 +56,7 @@ var implementation uses - ImageDLLLoader, ICOLoader, PNGLOader, HIPSLoader, BMPLoader, PCXLoader, WMFLoader, - LinarBitmap, FileUtils, JPEGLoader, JPEG, Registry, Global; + Registry, Global; {$R *.dfm} @@ -235,14 +234,7 @@ end; /////////////////////////////////////////////////////////////////////////////// procedure TfrmPostProcess.btnSaveClick(Sender: TObject); begin - with TLinearBitmap.Create do - try - Assign(FRenderer.GetImage); - JPEGLoader.Default.Quality := JPEGQuality; - SaveToFile(FImagename); - finally - Free; - end; + FRenderer.SaveImage(FImagename); end; ///////////////////////////////////////////////////////////////////////////////