FastImageOutput

Share your advanced PureBasic knowledge/code with the community.
S.M.
Enthusiast
Enthusiast
Posts: 118
Joined: Sat Apr 24, 2004 1:11 pm
Contact:

FastImageOutput

Post by S.M. »

Code: Select all

Structure DrawingInfoStruct 
  Type.l 
  Window.l 
  DC.l 
  ReleaseProcedure.l 
  PixelBuffer.l 
  Pitch.l 
  Width.l 
  Height.l 
  Depth.l 
  PixelFormat.l 
  StopDirectAccess.l 
  StartDirectAccess.l 
EndStructure 

Global FastImgOutputID.DrawingInfoStruct 

Procedure ___ReleaseFastImageOutput() 
  If FastImgOutputID\DC:DeleteDC_(FastImgOutputID\DC):FastImgOutputID\DC=0:EndIf ; free the created memory DC 
EndProcedure 

Procedure ___StopDirectAccess() 
  ProcedureReturn FastImgOutputID\DC 
EndProcedure 

Procedure ___StartDirectAccess() 
  GetPixel_(FastImgOutputID\DC,0,0) ; make sure all GDI operations are finished 
  ProcedureReturn FastImgOutputID\PixelBuffer 
EndProcedure 

; FastImageOutput() provides a faster pixel access for 32-,24- and 15 bit images(DIBSesctions). 
; However, for now only plot(x,y,color) works faster. (point(x,y) seems to be not optimized for direct memory access at the moment. You can use the PointFast() command from the E2D Userlib to get a faster point command.) 
Procedure FastImageOutput(Image) 
  If GetObject_(ImageID(Image),SizeOf(DIBSECTION),ds.DIBSECTION)=0 
    ProcedureReturn 0 ; no BITMAP/DIBSECTION 
  EndIf 
  If ds\dsBm\bmBits=0
    ProcedureReturn 0 ; no DIBSECTION
  EndIf

  FastImgOutputID\Type=7 ; allows direct memory access 
  FastImgOutputID\ReleaseProcedure=@___ReleaseFastImageOutput() 
  FastImgOutputID\PixelBuffer=ds\dsBm\bmBits+ds\dsBm\bmWidthBytes*(ds\dsBm\bmHeight-1) ;needed because the image if top down 
  FastImgOutputID\Pitch=-ds\dsBm\bmWidthBytes 
  FastImgOutputID\Width=ds\dsBm\bmWidth 
  FastImgOutputID\Height=ds\dsBm\bmHeight 

  Select ds\dsBm\bmBitsPixel  
    Case 32 
      FastImgOutputID\Depth=32 
      FastImgOutputID\PixelFormat=#PB_PixelFormat_32Bits_BGR 
    Case 24 
      FastImgOutputID\Depth=24
      FastImgOutputID\PixelFormat=#PB_PixelFormat_24Bits_BGR  
    Case 16 
      FastImgOutputID\Depth=15 
      FastImgOutputID\PixelFormat=#PB_PixelFormat_15Bits      
    Default 
      ProcedureReturn 0 ; only 32-,24- and 15bit DIBSections are supported 
  EndSelect 

  MemDC=CreateCompatibleDC_(0) 
  If MemDC=0:ProcedureReturn 0:EndIf ; the memory DC cannot be created 
  SelectObject_(MemDC,ImageID(Image)) 
  FastImgOutputID\DC=MemDC 

  FastImgOutputID\StopDirectAccess=@___StopDirectAccess() 
  FastImgOutputID\StartDirectAccess=@___StartDirectAccess()  
  ProcedureReturn FastImgOutputID 
EndProcedure 



;Test: 
OpenWindow(1,0,0,600,500,"FastImageOutput Test") 

CreateImage(1,600,500,32) ; only 32bit seems to be really faster... 

Start=GetTickCount_() 

StartDrawing(FastImageOutput(1)) ; replace this by ImageOutput(1) 
For Y=0 To 499 
For X=0 To 599 
  Plot(X,Y,X*Y) 
Next 
Next 
StopDrawing() 

Result=GetTickCount_()-Start 

StartDrawing(WindowOutput(1)) 
DrawImage(ImageID(1),0,0) 
StopDrawing() 
MessageRequester("Result:",Str(Result)+" ms")
E2D for PureBASIC v4.0
//edit:
Link corrected,thanks DoubleDutch
Last edited by S.M. on Mon Jun 26, 2006 8:39 am, edited 2 times in total.
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Your routine make it 6x faster than normal on my machine! :D

Fred: You should build this in!

btw: the link doesn't work.
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Post by djes »

:shock:
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

FastImageOuput() : 15ms
ImageOutput() : 125ms
8)

I noticed that ImageOutput() is bound-protected but not FastImageOutput().

Code: Select all

For Y=0 To 500 ;-1
  For X=0 To 600 ;-1
    Plot(X,Y,X*Y) 
  Next 
Next
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post by Xombie »

FastImageOutput(): 0ms - 16ms
ImageOutput(): 94ms

So... what's the catch? :) As the saying goes, if something sounds really good, it usually is :D
S.M.
Enthusiast
Enthusiast
Posts: 118
Joined: Sat Apr 24, 2004 1:11 pm
Contact:

Post by S.M. »

@Xombie
There is no hook.(At least I don't know any)
It just use the features of DIBSections.

You can even use direct memory access:

Code: Select all

*Buffer=DrawingBuffer()
Pitch=DrawingBufferPitch()
For Y=0 To 499 
*ptr.long=*Buffer+Pitch*Y
For X=0 To 599 
  *ptr\l=X*Y
  *ptr+4
Next 
Next
Fred: You should build this in!
Yes, please :D And a faster point command (wasn't this already included in 3.94 ?!?)

regards
Stefan
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

GetTickCount_() is too low-res for something this fast. When I turned the debugger off it was always showing 0 ms. So I added this routine and turned the debugger off, it executes in 5 ms vs. 193 ms normal ImageOutput():

Code: Select all

;By Rescator
Procedure.l Ticks_HQ() 
  Static maxfreq.q 
  Protected t.q 
  If maxfreq=0 
    QueryPerformanceFrequency_(@maxfreq) 
    maxfreq=maxfreq/1000 
  EndIf 
  QueryPerformanceCounter_(@t.q) 
  ProcedureReturn t/maxfreq 
EndProcedure 
BERESHEIT
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Post by djes »

Here it seems to be 20x faster!
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

you do you think that this difference of speed is due to the fact that FastImageOutput() is not protected against writing out of the image area ?
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
S.M.
Enthusiast
Enthusiast
Posts: 118
Joined: Sat Apr 24, 2004 1:11 pm
Contact:

Post by S.M. »

@Flype
No, it's because Plot() uses direct memory access in this case (like the example I posted above), instead of the SetPixel(V) API function.
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Post by Polo »

Flype wrote:you do you think that this difference of speed is due to the fact that FastImageOutput() is not protected against writing out of the image area ?
Not possible, the checking should only be done with the Debug library ?
Dr. Dri
Enthusiast
Enthusiast
Posts: 243
Joined: Sat Aug 23, 2003 6:45 pm

Post by Dr. Dri »

where did you get the DrawingInfoStruct structure ?
in the purebasic library descriptor there is

Code: Select all

Structure DrawingInfoStruct
  Type.l
  Window.l
  DC.l
  ReleaseProcedure.l
  PixelBuffer.l
  Pitch.l
  Width.l
  Height.l
  Depth.l
  PixelFormat.l
EndStructure
Dri :?:
S.M.
Enthusiast
Enthusiast
Posts: 118
Joined: Sat Apr 24, 2004 1:11 pm
Contact:

Post by S.M. »

Dr. Dri wrote:in the purebasic library descriptor there is
It's even only:

Code: Select all

  Structure DrawingInfoStruct
  	Type.l    ; Type of the DC
  	Window.l  ; Window associated to the DC (if any)
  	DC.l      ; DC
  	ReleaseProcedure.l ; Address to a procedure to release the DC when StopDrawing() is called 
  	PixelBuffer.l      ; Address of the memory pixel buffer (DirectX)
  	Pitch.l            ; Pitch
  	Width.l
  	Height.l
  	Depth.l
  EndStructure
Dr. Dri wrote:where did you get the DrawingInfoStruct structure ?
Reverse Engineering (whitout dissasembling anything)
I just looked at the pointer which SpriteOutput() returns.
dige
Addict
Addict
Posts: 1391
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Post by dige »

With FastImageOutput() I have got some strange illegal memory
access errors....

@Fred: what du you think about that way?
S.M.
Enthusiast
Enthusiast
Posts: 118
Joined: Sat Apr 24, 2004 1:11 pm
Contact:

Post by S.M. »

@dige
With the same code posted above ?
Post Reply