Page 1 of 1

Drawing for Steven

Posted: Fri Feb 03, 2012 2:15 pm
by oryaaaaa
This code dump the limitations of PureBasic. (8192x8192)
Now, I use WindowsXP. But I don't have 8192x8192 limit.
Really Cool !!!!
Thanks :D

This test code is for the display. (PB4.60 Windows x86)

Code: Select all

;
;  Drawing for Steven ( Drawing of 4x4 )
;  From My product "Art photo print"
;  Author oryaaaaa
;  2011/10/05 15:00
;
;  This code is for Printer output A2/A3W or 32000x32000 Printer pixel output
;  coz Invalid memory access on WindowsXP ( This code use Loophole. )
;
;  The meaning of 4s is 4x4. I wrote this code on the day of the fate. 
;  

UseJPEGImageDecoder()

Enumeration
  #Window_Preview
  #TemporaryImage
  #TemporaryImage1
  #TemporaryImage2
  #TemporaryImage3
  #TemporaryImage4 
  #Image
EndEnumeration

Global *Imagebuffer

Procedure CopyMemoryToImage(Memory.l,ImageNumber.l)
  Protected TemporaryDC.l, TemporaryBitmap.BITMAP, TemporaryBitmapInfo.BITMAPINFO
  TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
  GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)
  TemporaryBitmapInfo\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
  TemporaryBitmapInfo\bmiHeader\biWidth       = TemporaryBitmap\bmWidth
  TemporaryBitmapInfo\bmiHeader\biHeight      = -TemporaryBitmap\bmHeight
  TemporaryBitmapInfo\bmiHeader\biPlanes      = 1
  TemporaryBitmapInfo\bmiHeader\biBitCount    = 32
  TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB
  SetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, Memory, TemporaryBitmapInfo, #DIB_RGB_COLORS)
  DeleteDC_(TemporaryDC)
EndProcedure

Procedure DrawImage4s(OriginalImage.l, dx.l, dy.l, dw.l, dh.l)
  Protected TemporaryImage.l, MemorySizeOrigin.l, MemorySizeTarget.l
  Protected *MemoryOrigin, *MemoryTarget1,*MemoryTarget2
  Protected *MemoryTarget3,*MemoryTarget4
  Protected MemorySizeTarget2.l, Origindata.l
  Protected Origin.l, Target.l, W.l, H.l, X.l, Y.l, Image1.l, Image2.l, Image3.l, Image4.l, PlusH.l, PlusHPos.l
  Protected PlusW.l, Plusdw.l, Plusdh.l
  ;
  SetPriorityClass_(GetCurrentProcess_(),#REALTIME_PRIORITY_CLASS) 
  ;
  PlusW = ImageWidth(OriginalImage) % 4
  PlusH = ImageHeight(OriginalImage) % 4
  Plusdw = dw % 4
  Plusdh = dh % 4
  ;
  CreateImage(#TemporaryImage1,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4), 24)
  CreateImage(#TemporaryImage2,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4), 24)
  CreateImage(#TemporaryImage3,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4), 24)
  CreateImage(#TemporaryImage4,  Int(ImageWidth(OriginalImage)/4+PlusW),Int(ImageHeight(OriginalImage)/4), 24)
  ;
  MemorySizeOrigin = (ImageWidth(OriginalImage) * ImageHeight(OriginalImage) << 2)
  MemorySizeTarget = ((ImageWidth(#TemporaryImage1)+PlusW) * (ImageHeight(#TemporaryImage1)+PlusH) << 2)
  MemorySizeTarget2 = ((ImageWidth(#TemporaryImage4)) * (ImageHeight(#TemporaryImage4)+PlusH) << 2)
  ;
  *MemoryOrigin =  *Imagebuffer
  *MemoryTarget1 = AllocateMemory(MemorySizeTarget)
  *MemoryTarget2 = AllocateMemory(MemorySizeTarget)
  *MemoryTarget3 = AllocateMemory(MemorySizeTarget)
  *MemoryTarget4 = AllocateMemory(MemorySizeTarget2)
  ;
  W = ImageWidth(OriginalImage)
  H = ImageHeight(OriginalImage)
  PlusHPos = Int(H/4)
  Image1 = Int(W/4)
  Image2 = Image1
  Image3 = Image1 + Image2
  Image4 = Image1 + Image3
  ImageA= 0
  ;
  For n=0 To 2
    For Y = n*Int(H/4) To PlusHPos - 1 
      For X = 0 To W - 1
        Origin = (Y * W + X) << 2 
        Origindata = PeekL(*MemoryOrigin + Origin) & $FFFFFF
        Select X
          Case 0 To (Image1-1)
            ImageA =((Y-n*Int(H/4))*Image1+X)*4
            PokeL(*MemoryTarget1 + ImageA, Origindata)  
          Case Image2 To (Image3-1)
            ImageA = ((Y-n*Int(H/4))*(Image3-Image2)+X-Image2)*4
            PokeL(*MemoryTarget2 + ImageA, Origindata)  
          Case Image3 To (Image4-1)
            ImageA = ((Y-n*Int(H/4))*(Image4-Image3)+X-Image3)*4
            PokeL(*MemoryTarget3 + ImageA, Origindata) 
          Case Image4 To (W-1)
            ImageA = ((Y-n*Int(H/4))*(W-Image4)+X-Image4)*4
            PokeL(*MemoryTarget4 + ImageA, Origindata)  
        EndSelect
      Next
    Next
    ResizeImage(#TemporaryImage1, Image1, Int(H/4))
    ResizeImage(#TemporaryImage2, Image3-Image2, Int(H/4))
    ResizeImage(#TemporaryImage3, Image4-Image3, Int(H/4))
    ResizeImage(#TemporaryImage4, W-Image4, Int(H/4))
    CopyMemoryToImage(*MemoryTarget1, #TemporaryImage1)
    CopyMemoryToImage(*MemoryTarget2, #TemporaryImage2)
    CopyMemoryToImage(*MemoryTarget3, #TemporaryImage3)
    CopyMemoryToImage(*MemoryTarget4, #TemporaryImage4)
    DrawImage(ImageID(#TemporaryImage1), dx,dy+Int(dh/4)*n,Int(dw/4), Int(dh/4))
    DrawImage(ImageID(#TemporaryImage2), dx+Int(dw/4),dy+Int(dh/4)*n,Int(dw/4),Int(dh/4))
    DrawImage(ImageID(#TemporaryImage3), dx+Int(dw/4)*2,dy+Int(dh/4)*n,Int(dw/4),Int(dh/4))
    DrawImage(ImageID(#TemporaryImage4), dx+Int(dw/4)*3,dy+Int(dh/4)*n,Int(dw/4)+Plusdw,Int(dh/4))
    PlusHPos + Int(H/4)
  Next
  ;
  PlusHPos - Int(H/4)
  ;
  For Y=PlusHPos To H-1
    For X = 0 To W - 1
      Origin = (Y * W + X) << 2 
      Origindata = PeekL(*MemoryOrigin + Origin) & $FFFFFF
      Select X
        Case 0 To (Image1-1)
          ImageA =((Y-PlusHPos)*Image1+X)*4
          PokeL(*MemoryTarget1 + ImageA, Origindata) 
        Case Image2 To (Image3-1)
          ImageA = ((Y-PlusHPos)*(Image3-Image2)+X-Image2)*4
          PokeL(*MemoryTarget2 + ImageA, Origindata)   
        Case Image3 To (Image4-1)
          ImageA = ((Y-PlusHPos)*(Image4-Image3)+X-Image3)*4
          PokeL(*MemoryTarget3 + ImageA, Origindata)   
        Case Image4 To (W-1)
          ImageA = ((Y-PlusHPos)*(W-Image4)+X-Image4)*4
          PokeL(*MemoryTarget4 + ImageA, Origindata)   
      EndSelect
    Next
  Next        
  ;
  ResizeImage(#TemporaryImage1,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4)+PlusH)
  ResizeImage(#TemporaryImage2,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4)+PlusH)
  ResizeImage(#TemporaryImage3,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4)+PlusH)
  ResizeImage(#TemporaryImage4,  Int(ImageWidth(OriginalImage)/4)+PlusW,Int(ImageHeight(OriginalImage)/4)+PlusH) 
  CopyMemoryToImage(*MemoryTarget1, #TemporaryImage1)
  CopyMemoryToImage(*MemoryTarget2, #TemporaryImage2)
  CopyMemoryToImage(*MemoryTarget3, #TemporaryImage3)
  CopyMemoryToImage(*MemoryTarget4, #TemporaryImage4)
  DrawImage(ImageID(#TemporaryImage1), dx,                       dy+Int(dh/4)*3,Int(dw/4), Int(dh/4)+Plusdh)
  DrawImage(ImageID(#TemporaryImage2), dx+Int(dw/4),     dy+Int(dh/4)*3,Int(dw/4),Int(dh/4)+Plusdh)
  DrawImage(ImageID(#TemporaryImage3), dx+Int(dw/4)*2, dy+Int(dh/4)*3,Int(dw/4),Int(dh/4)+Plusdh)
  DrawImage(ImageID(#TemporaryImage4), dx+Int(dw/4)*3, dy+Int(dh/4)*3,Int(dw/4)+Plusdw,Int(dh/4)+Plusdh) 
  FreeImage(#TemporaryImage1)
  FreeImage(#TemporaryImage2)
  FreeImage(#TemporaryImage3)
  FreeImage(#TemporaryImage4)
  FreeMemory(*MemoryTarget1)
  FreeMemory(*MemoryTarget2) 
  FreeMemory(*MemoryTarget3)
  FreeMemory(*MemoryTarget4) 
  ;
  SetPriorityClass_(GetCurrentProcess_(),#NORMAL_PRIORITY_CLASS)  
EndProcedure

Procedure Box4s(pw.l,ph.l,pcolor.l, px.l=0, py.l=0)
  Protected X1.l, y1.l
  Protected pwx.l  = Int(pw/4)
  Protected Pwy.l  = Int(ph/4)
  For X1=0 To 3
    For y1=0 To 3
      Box(X1*pwx+px, y1*Pwy+py, pwx+pw%4,Pwy+ph%4, pcolor)
    Next 
  Next
EndProcedure

Procedure Main()
  Protected File.l, *buffer, length.l, LoadFlag.l
  Protected SP_X.l, SP_Y.l, Temp.l, Color_from.l, filepath.s
  filepath = OpenFileRequester("Image file","*.jpg","*.jpg | *.jpg",0)
  File = ReadFile(#PB_Any, filepath)
  length = Lof(File)
  *buffer = AllocateMemory(length)
  ReadData(File, *buffer, length)
  CloseFile(File)
  LoadFlag = CatchImage(#Image, *buffer, length) 
  FreeMemory(*buffer) 
  If LoadFlag
    SetPriorityClass_(GetCurrentProcess_(),#REALTIME_PRIORITY_CLASS)  
    ;
    CreateImage(#TemporaryImage, ImageWidth(#Image), ImageHeight(#Image), 32) 
    StartDrawing(ImageOutput(#TemporaryImage))
      *Imagebuffer = DrawingBuffer() 
    StopDrawing()
    StartDrawing(ImageOutput(#Image))
      For SP_Y=0 To OutputHeight()-1
        For SP_X=0 To OutputWidth()-1
          Temp = (SP_Y*OutputWidth()+ SP_X) << 2
          Color_from = Point(SP_X, SP_Y) 
          Color_from = Red(Color_from)<<16 + Green(Color_from)<<8 + Blue(Color_from) 
          PokeL(*Imagebuffer+Temp, Color_from)
        Next
      Next
    StopDrawing()
    FreeImage(#Image)
    StartDrawing(ImageOutput(#TemporaryImage))
      *Imagebuffer = DrawingBuffer() 
    StopDrawing()
    ;
    SetPriorityClass_(GetCurrentProcess_(),#NORMAL_PRIORITY_CLASS)  
    ;
    ExamineDesktops() 
    OpenWindow(#Window_Preview, 0, 0, Int(DesktopWidth(0)*0.9),Int(DesktopHeight(0)*0.9), "Preview"+Space(3)+"Drawing", #PB_Window_ScreenCentered)
    StickyWindow(#Window_Preview,#True)
    ;
    ; This code is for PrinterOutput.
    StartDrawing(WindowOutput(#Window_Preview))
      Box4s(OutputWidth(),OutputHeight(),0)
      DrawImage4s(#TemporaryImage, 50, 50, OutputWidth()-100, OutputHeight()-100) 
    StopDrawing() 
    ;
    ;
    FreeImage(#TemporaryImage)
    SetWindowTitle(#Window_Preview, "Preview"+Space(3)+"Exit=Anykey")
    Repeat
      event = WindowEvent()
      Delay(1)
    Until event=#WM_KEYDOWN
    StickyWindow(#Window_Preview,#False)
    CloseWindow(#Window_Preview)
  EndIf
EndProcedure
  
Main()

End
If it is possible, could you optimize this code for more speed.

Re: Drawing for Steven

Posted: Fri Feb 03, 2012 2:40 pm
by Fred
Great virtual image paging !

Re: Drawing for Steven

Posted: Sat Feb 04, 2012 11:42 am
by Kwai chang caine
Works great, thanks for sharing 8)

Re: Drawing for Steven

Posted: Mon Feb 06, 2012 12:06 am
by citystate
k, I'll bite... who is Steven? (does he use windows 7?) :P

Re: Drawing for Steven

Posted: Mon Feb 06, 2012 3:59 am
by oryaaaaa
@citystate

WQHD 2560x1440 Wallpaper by Art photo print
http://purebasic.coolverse.jp/_userdata/steven.jpg

Could you set this Wallpaper in your pc?

Re: Drawing for Steven

Posted: Sun Feb 26, 2012 7:20 pm
by oryaaaaa
4x faster code

Code: Select all

;
;  Drawing for Steven ( Drawing of 4x4 )
;  From My product "Art photo print"
;  Author oryaaaaa
;  2011/10/05 15:00
;  Version 1.1 4x Faster 2012/12/27 3:00
;
;  This code is for Printer output A2/A3W or 32000x32000 Printer pixel output
;  coz Invalid memory access on WindowsXP ( This code use Loophole. )
;
;  The meaning of 4s is 4x4. I wrote this code on the day of the fate. 
;  

UseJPEGImageDecoder()

Structure FastImage
  *buffer
  width.l
  height.l
  mode.b
  id.l
EndStructure

Global V_art.FastImage, V_tmp.FastImage

Enumeration
  #Window_Preview
  #TemporaryImage
  #TemporaryImage1
  #TemporaryImage2
  #TemporaryImage3
  #TemporaryImage4 
  #Image
EndEnumeration

Procedure Int24ToInt32(*in_buf, *out_buf, num_samples.l)
  !MOV Eax, [p.p_in_buf]
  !MOV Edx, [p.p_out_buf]
  !MOV Ecx, [p.v_num_samples]
  !PUSH Ebx
  !int24int32loop:
  !MOV Ebx, [Eax]
  !MOV byte [Edx], bl
  !MOV byte [Edx+1], bh
  !MOV Ebx, [Eax+2]
  !MOV byte [Edx+2], bl
  !MOV byte [Edx+3], 0xFF
  !ADD Eax, 3
  !ADD Edx, 4
  !DEC Ecx
  !JNZ int24int32loop
  !POP Ebx 
EndProcedure
  
Procedure Int32ToInt24(*in_buf, *out_buf, num_samples.l)
  !MOV Eax, [p.p_in_buf]
  !MOV Edx, [p.p_out_buf]
  !MOV Ecx, [p.v_num_samples]
  !PUSH Ebx
  !int32int24loop:
  !MOV Ebx, [Eax]
  !MOV byte [Edx], bl
  !MOV byte [Edx+1], bh
  !MOV Ebx, [Eax+2]
  !MOV byte [Edx+2], bl
  !ADD Eax, 4
  !ADD Edx, 3
  !DEC Ecx
  !JNZ int32int24loop
  !MOV byte [Edx], 0 
  !MOV byte [Edx+1], 0
  !POP Ebx
EndProcedure

Procedure DrawImage4s(OriginalImage.l, dx.l, dy.l, dw.l, dh.l)
  Protected TemporaryImage.l, MemorySizeOrigin.l, MemorySizeTarget.l
  Protected *MemoryOrigin, *MemoryTarget1,*MemoryTarget2
  Protected *MemoryTarget3,*MemoryTarget4
  Protected MemorySizeTarget2.l, add.b
  Protected Origin.l, W.l, H.l, X.l, Y.l, Image1.l, Image2.l, Image3.l, Image4.l, PlusH.l, PlusHPos.l
  Protected PlusW.l, Plusdw.l, Plusdh.l, YY.l, tmp_o.l, tmp_i.l
  
  SetPriorityClass_(GetCurrentProcess_(),#REALTIME_PRIORITY_CLASS) 
  
  PlusW = ImageWidth(OriginalImage) % 4
  PlusH = ImageHeight(OriginalImage) % 4
  Plusdw = dw % 4
  Plusdh = dh % 4
  
  CreateImage(#TemporaryImage1,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4), 24)
  CreateImage(#TemporaryImage2,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4), 24)
  CreateImage(#TemporaryImage3,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4), 24)
  CreateImage(#TemporaryImage4,  Int(ImageWidth(OriginalImage)/4+PlusW),Int(ImageHeight(OriginalImage)/4), 24)
  
  MemorySizeOrigin = (ImageWidth(OriginalImage) * ImageHeight(OriginalImage) << 2)
  MemorySizeTarget = ((ImageWidth(#TemporaryImage1)+PlusW) * (ImageHeight(#TemporaryImage1)+PlusH) << 2)
  MemorySizeTarget2 = ((ImageWidth(#TemporaryImage4)) * (ImageHeight(#TemporaryImage4)+PlusH) << 2)
  
  
  *MemoryOrigin = V_art\Buffer
  *MemoryTarget1 = AllocateMemory(MemorySizeTarget)
  *MemoryTarget2 = AllocateMemory(MemorySizeTarget)
  *MemoryTarget3 = AllocateMemory(MemorySizeTarget)
  *MemoryTarget4 = AllocateMemory(MemorySizeTarget2)
  
  W = ImageWidth(OriginalImage)
  H = ImageHeight(OriginalImage)
  PlusHPos = Int(H/4)
  Image1 = Int(W/4)
  Image2 = Image1
  Image3 = Image1 + Image2
  Image4 = Image1 + Image3
  ImageA= 0
  
  For n=0 To 2
    For Y = n*Int(H/4) To PlusHPos - 1 
      YY = PlusHPos-Y-1
      Origin = (H-Y-1) *W << 2 
      ImageA =(YY*Image1)*4
      CopyMemory(*MemoryOrigin + Origin,*MemoryTarget1 + ImageA, 4*Image1) 
      Origin = ((H-Y-1) * W + Image2) << 2 
      ImageA = (YY*(Image3-Image2))*4
      CopyMemory(*MemoryOrigin + Origin,*MemoryTarget2 + ImageA, 4*(Image3-Image2)) 
      Origin = ((H-Y-1) * W + Image3) << 2 
      ImageA = (YY*(Image4-Image3))*4
      CopyMemory(*MemoryOrigin + Origin,*MemoryTarget3 + ImageA, 4*(Image4-Image3)) 
      Origin = ((H-Y-1) * W + Image4) << 2 
      ImageA = (YY*(W-Image4))*4
      CopyMemory(*MemoryOrigin + Origin,*MemoryTarget4 + ImageA, 4*(W-Image4)) 
    Next
    ResizeImage(#TemporaryImage1, Image1, Int(H/4))
    ResizeImage(#TemporaryImage2, Image3-Image2, Int(H/4))
    ResizeImage(#TemporaryImage3, Image4-Image3, Int(H/4))
    ResizeImage(#TemporaryImage4, W-Image4, Int(H/4))
    IsImage(#TemporaryImage1)
    IsImage(#TemporaryImage2)
    IsImage(#TemporaryImage3)
    IsImage(#TemporaryImage4)
    StartDrawing(ImageOutput(#TemporaryImage1))
      V_tmp\Buffer = DrawingBuffer() 
      V_tmp\width  = ImageWidth(#TemporaryImage1)
      V_tmp\height = ImageHeight(#TemporaryImage1)
    StopDrawing()
    tmp_i = 0 : tmp_o = 0
    For Y=0 To V_tmp\height -1
      Int32ToInt24(*MemoryTarget1+tmp_i, V_tmp\Buffer+tmp_o, V_tmp\width)   
      tmp_i + V_tmp\width*4 : tmp_o + V_tmp\width*3+V_tmp\width%4
    Next
    StartDrawing(ImageOutput(#TemporaryImage2))
      V_tmp\Buffer = DrawingBuffer() 
      V_tmp\width  = ImageWidth(#TemporaryImage2)
      V_tmp\height = ImageHeight(#TemporaryImage2)
    StopDrawing()
    tmp_i = 0 : tmp_o = 0
    For Y=0 To V_tmp\height -1
      Int32ToInt24(*MemoryTarget2+tmp_i, V_tmp\Buffer+tmp_o, V_tmp\width)   
      tmp_i + V_tmp\width*4 : tmp_o + V_tmp\width*3+V_tmp\width%4
    Next
    StartDrawing(ImageOutput(#TemporaryImage3))
      V_tmp\Buffer = DrawingBuffer() 
      V_tmp\width  = ImageWidth(#TemporaryImage3)
      V_tmp\height = ImageHeight(#TemporaryImage3)
    StopDrawing()
    tmp_i = 0 : tmp_o = 0
    For Y=0 To V_tmp\height -1
      Int32ToInt24(*MemoryTarget3+tmp_i, V_tmp\Buffer+tmp_o, V_tmp\width)   
      tmp_i + V_tmp\width*4 : tmp_o + V_tmp\width*3+V_tmp\width%4
    Next
    StartDrawing(ImageOutput(#TemporaryImage4))
      V_tmp\Buffer = DrawingBuffer() 
      V_tmp\width  = ImageWidth(#TemporaryImage4)
      V_tmp\height = ImageHeight(#TemporaryImage4)
    StopDrawing()
    tmp_i = 0 : tmp_o = 0
    For Y=0 To V_tmp\height -1
      Int32ToInt24(*MemoryTarget4+tmp_i, V_tmp\Buffer+tmp_o, V_tmp\width)   
      tmp_i + V_tmp\width*4 : tmp_o + V_tmp\width*3+V_tmp\width%4
    Next
    ;  
    StartDrawing(WindowOutput(V_tmp\id))
      DrawImage(ImageID(#TemporaryImage1), dx,dy+Int(dh/4)*n,Int(dw/4), Int(dh/4))
      DrawImage(ImageID(#TemporaryImage2), dx+Int(dw/4),dy+Int(dh/4)*n,Int(dw/4),Int(dh/4))
      DrawImage(ImageID(#TemporaryImage3), dx+Int(dw/4)*2,dy+Int(dh/4)*n,Int(dw/4),Int(dh/4))
      DrawImage(ImageID(#TemporaryImage4), dx+Int(dw/4)*3,dy+Int(dh/4)*n,Int(dw/4)+Plusdw,Int(dh/4))
    StopDrawing()
    
    PlusHPos + Int(H/4)
  Next
  
  PlusHPos - Int(H/4)
  For Y=PlusHPos To H-1
    YY = H-Y-1
    Origin = ((H-Y-1) * W + 0) << 2 
    ImageA =(YY*Image1+0)*4
    CopyMemory(*MemoryOrigin + Origin,*MemoryTarget1 + ImageA, 4*Image1) 
    Origin = ((H-Y-1) * W + Image2) << 2 
    ImageA = (YY*(Image3-Image2))*4
    CopyMemory(*MemoryOrigin + Origin,*MemoryTarget2 + ImageA, 4*(Image3-Image2)) 
    Origin = ((H-Y-1) * W + Image3) << 2 
    ImageA = (YY*(Image4-Image3))*4
    CopyMemory(*MemoryOrigin + Origin,*MemoryTarget3 + ImageA, 4*(Image4-Image3)) 
    Origin = ((H-Y-1) * W + Image4) << 2 
    ImageA = (YY*(W-Image4))*4
    CopyMemory(*MemoryOrigin + Origin,*MemoryTarget4 + ImageA, 4*(W-Image4)) 
  Next        
  
  ResizeImage(#TemporaryImage1,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4)+PlusH)
  ResizeImage(#TemporaryImage2,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4)+PlusH)
  ResizeImage(#TemporaryImage3,  Int(ImageWidth(OriginalImage)/4),Int(ImageHeight(OriginalImage)/4)+PlusH)
  ResizeImage(#TemporaryImage4,  Int(ImageWidth(OriginalImage)/4)+PlusW,Int(ImageHeight(OriginalImage)/4)+PlusH) 
  IsImage(#TemporaryImage1)
  IsImage(#TemporaryImage2)
  IsImage(#TemporaryImage3)
  IsImage(#TemporaryImage4)
  StartDrawing(ImageOutput(#TemporaryImage1))
    V_tmp\Buffer = DrawingBuffer() 
    V_tmp\width  = ImageWidth(#TemporaryImage1)
    V_tmp\height = ImageHeight(#TemporaryImage1)
  StopDrawing()
  tmp_i = 0 : tmp_o = 0
  For Y=0 To V_tmp\height -1
    Int32ToInt24(*MemoryTarget1+tmp_i, V_tmp\Buffer+tmp_o, V_tmp\width)   
    tmp_i + V_tmp\width*4 : tmp_o + V_tmp\width*3+V_tmp\width%4
  Next
  StartDrawing(ImageOutput(#TemporaryImage2))
    V_tmp\Buffer = DrawingBuffer() 
    V_tmp\width  = ImageWidth(#TemporaryImage2)
    V_tmp\height = ImageHeight(#TemporaryImage2)
  StopDrawing()
  tmp_i = 0 : tmp_o = 0
  For Y=0 To V_tmp\height -1
    Int32ToInt24(*MemoryTarget2+tmp_i, V_tmp\Buffer+tmp_o, V_tmp\width)   
    tmp_i + V_tmp\width*4 : tmp_o + V_tmp\width*3+V_tmp\width%4
  Next
  StartDrawing(ImageOutput(#TemporaryImage3))
    V_tmp\Buffer = DrawingBuffer() 
    V_tmp\width  = ImageWidth(#TemporaryImage3)
    V_tmp\height = ImageHeight(#TemporaryImage3)
  StopDrawing()
  tmp_i = 0 : tmp_o = 0
  For Y=0 To V_tmp\height -1
    Int32ToInt24(*MemoryTarget3+tmp_i, V_tmp\Buffer+tmp_o, V_tmp\width)   
    tmp_i + V_tmp\width*4 : tmp_o + V_tmp\width*3+V_tmp\width%4
  Next
  StartDrawing(ImageOutput(#TemporaryImage4))
    V_tmp\Buffer = DrawingBuffer() 
    V_tmp\width  = ImageWidth(#TemporaryImage4)
    V_tmp\height = ImageHeight(#TemporaryImage4)
  StopDrawing()
  tmp_i = 0 : tmp_o = 0
  For Y=0 To V_tmp\height -1
    Int32ToInt24(*MemoryTarget4+tmp_i, V_tmp\Buffer+tmp_o, V_tmp\width)   
    tmp_i + V_tmp\width*4 : tmp_o + V_tmp\width*3+V_tmp\width%4
  Next
  ;  
  StartDrawing(WindowOutput(V_tmp\id))
    DrawImage(ImageID(#TemporaryImage1), dx,                       dy+Int(dh/4)*3,Int(dw/4), Int(dh/4)+Plusdh)
    DrawImage(ImageID(#TemporaryImage2), dx+Int(dw/4),     dy+Int(dh/4)*3,Int(dw/4),Int(dh/4)+Plusdh)
    DrawImage(ImageID(#TemporaryImage3), dx+Int(dw/4)*2, dy+Int(dh/4)*3,Int(dw/4),Int(dh/4)+Plusdh)
    DrawImage(ImageID(#TemporaryImage4), dx+Int(dw/4)*3, dy+Int(dh/4)*3,Int(dw/4)+Plusdw,Int(dh/4)+Plusdh) 
  StopDrawing()
  FreeImage(#TemporaryImage1)
  FreeImage(#TemporaryImage2)
  FreeImage(#TemporaryImage3)
  FreeImage(#TemporaryImage4)
  FreeMemory(*MemoryTarget1)
  FreeMemory(*MemoryTarget2) 
  FreeMemory(*MemoryTarget3)
  FreeMemory(*MemoryTarget4) 
  
  SetPriorityClass_(GetCurrentProcess_(),#NORMAL_PRIORITY_CLASS) 
EndProcedure

Procedure Box4s(pw.l,ph.l,pcolor.l, px.l=0, py.l=0)
  Protected X1.l, y1.l
  Protected pwx.l  = Int(pw/4)
  Protected Pwy.l  = Int(ph/4)
  StartDrawing(WindowOutput(V_tmp\id)) 
  For X1=0 To 3
    For y1=0 To 3
      Box(X1*pwx+px, y1*Pwy+py, pwx+pw%4,Pwy+ph%4, pcolor)
    Next 
  Next
  StopDrawing()
EndProcedure

Procedure Main()
  Protected File.l, *buffer, length.l, LoadFlag.l, d_x.l, d_y.l,Y.l, add.b
  Protected SP_X.l, SP_Y.l, Temp.l, Color_from.l, filepath.s
  filepath = OpenFileRequester("Image file","*.jpg","*.jpg | *.jpg",0)
  File = ReadFile(#PB_Any, filepath)
  length = Lof(File)
  *buffer = AllocateMemory(length)
  ReadData(File, *buffer, length)
  CloseFile(File)
  LoadFlag = CatchImage(#Image, *buffer, length) 
  FreeMemory(*buffer) 
  If LoadFlag
    ;
    CreateImage(#TemporaryImage, ImageWidth(#Image), ImageHeight(#Image), 32) 
    StartDrawing(ImageOutput(#Image))
      V_art\Buffer = DrawingBuffer()
      V_art\width  = OutputWidth()
      V_art\height = OutputHeight()
    StopDrawing()
    StartDrawing(ImageOutput(#TemporaryImage))
      V_tmp\Buffer = DrawingBuffer() 
      V_tmp\width  = V_art\width
      V_tmp\height = V_art\height
    StopDrawing()
    IsImage(#TemporaryImage)
    ;
    For Y=0 To V_art\height -1
      Int24ToInt32(V_art\Buffer, V_tmp\Buffer, V_art\width)  
      V_art\Buffer + V_art\width*3 +V_art\width%4 :  V_tmp\Buffer + V_art\width*4
    Next
    ;
    ExamineDesktops() 
    d_x =Int(DesktopWidth(0)*0.9) : d_y = Int(DesktopHeight(0)*0.9)
    OpenWindow(#Window_Preview, 0, 0,d_x, d_y, "Preview"+Space(3)+"Drawing", #PB_Window_ScreenCentered)
    StickyWindow(#Window_Preview,#True)
    StartDrawing(ImageOutput(#TemporaryImage))
      V_art\Buffer = DrawingBuffer()
    StopDrawing()
    ;
    ; This code is for PrinterOutput.
    V_tmp\id = #Window_Preview
    Box4s(d_x, d_y,0)
    DrawImage4s(#TemporaryImage, 50, 50, d_x-100, d_y-100) 
    ;
    FreeImage(#TemporaryImage)
    SetWindowTitle(#Window_Preview, "Preview"+Space(3)+"Exit=Anykey")
    Repeat
      event = WindowEvent()
      Delay(1)
    Until event=#WM_KEYDOWN
    StickyWindow(#Window_Preview,#False)
    CloseWindow(#Window_Preview)
  EndIf
EndProcedure
  
Main()

End

Re: Drawing for Steven

Posted: Sun Feb 26, 2012 8:51 pm
by Michael Vogel
I would check if some other tuning could be done...
• n&3 should be faster than n%4
• n>>2 faster than Int(n/4)
• calculating offsets outside a loop (tmp_w_add=V_tmp\width*3+V_tmp\width&3) and using the value in the loop (tmp_w+tmp_w_add)
• eliminating useless code, e.g.IsImage(#TemporaryImage)
• simplifying the code, e.g.If LoadImage(#Image,filepath) instead of File = ReadFile(#PB_Any, filepath) .... If LoadFlag
• etc.

Re: Drawing for Steven

Posted: Sun Feb 26, 2012 9:01 pm
by Thorium
First needs to get it stable. It crashes on my system using the .jpg you provided.

Re: Drawing for Steven

Posted: Sun Feb 26, 2012 11:57 pm
by oryaaaaa
@Michael Vogel
Thank you. This code is snippets. IsImage calling must use before ImageWidth() or ImageHeight().
Maybe PureBasic Bug. and This code for not play, I must strict calculated it.

@Thorium
It is a very easy trouble.

Code: Select all

    add = V_art\width*3 +V_art\width%4 : add2 = V_art\width*4
    For Y=0 To V_art\height -1
      Int24ToInt32(V_art\Buffer, V_tmp\Buffer, V_art\width)  
      V_art\Buffer + add :  V_tmp\Buffer + add2
    Next
You should check "add" about Jpeg width.

Code: Select all

Procedure Int24ToInt32(*in_buf, *out_buf, num_samples.l)
  !MOV Eax, [p.p_in_buf]
  !MOV Edx, [p.p_out_buf]
  !MOV Ecx, [p.v_num_samples]
  !DEC Ecx ;/ here
  !PUSH Ebx
  !int24int32loop:
  !MOV Ebx, [Eax]
  !MOV byte [Edx], bl
  !MOV byte [Edx+1], bh
  !MOV Ebx, [Eax+2]
  !MOV byte [Edx+2], bl
  !MOV byte [Edx+3], 0xFF
  !ADD Eax, 3
  !ADD Edx, 4
  !DEC Ecx
  !JNZ int24int32loop
  !POP Ebx 
EndProcedure

Re: Drawing for Steven

Posted: Mon Feb 27, 2012 9:30 am
by oryaaaaa
FIXED "EBX to BX"

Code: Select all

Procedure Int24ToInt32(*in_buf, *out_buf, num_samples.l)
  !MOV Eax, [p.p_in_buf]
  !MOV Edx, [p.p_out_buf]
  !MOV Ecx, [p.v_num_samples]
;  !DEC Ecx
  !PUSH Ebx
  !int24int32loop:
  !MOV bx, [Eax]
  !MOV byte [Edx], bl
  !MOV byte [Edx+1], bh
  !MOV bx, [Eax+1]
  !MOV byte [Edx+2], bh
  !MOV byte [Edx+3], 0xFF
  !ADD Eax, 3
  !ADD Edx, 4
  !DEC Ecx
  !JNZ int24int32loop
  !POP Ebx 
EndProcedure
  
Procedure Int32ToInt24(*in_buf, *out_buf, num_samples.l)
  !MOV Eax, [p.p_in_buf]
  !MOV Edx, [p.p_out_buf]
  !MOV Ecx, [p.v_num_samples]
  !PUSH Ebx
  !int32int24loop:
  !MOV bx, [Eax]
  !MOV byte [Edx], bl
  !MOV byte [Edx+1], bh
  !MOV bx, [Eax+1]
  !MOV byte [Edx+2], bh
  !ADD Eax, 4
  !ADD Edx, 3
  !DEC Ecx
  !JNZ int32int24loop
  !POP Ebx
EndProcedure