ok, I've figured out the 16 bit problem, hopefully! I just need someone to test it for me as I don't have xp.
;Paste Image from Clipboard function, by markcw on 29/07/06
Graphics3D 640,480,0,2
SetBuffer BackBuffer()
image=PasteImageFromClipboard() ;paste image from clipboard
width=ImageWidth(image) ;get image info
height=ImageHeight(image)
While Not KeyHit(1)
Cls
DrawImage image,50,50 ;draw the image
Text 0,0,"image="+image+" width="+width+" height="+height
Flip
Wend
Function PasteImageFromClipboard()
;Paste the clipboard to a new Blitz3D image
;From "Copying a DIB to the clipboard", by John Simmons
;(http://www.codeproject.com)
Local hDIB,himage,pbmi,btmp,sizeInfo,sizePal,width,height,bpp
Local sizeBits,sizeDIB,x,y,offset,index,bytespp
;receive the bitmap from the clipboard as a DIB
If Api_OpenClipboard(0) ;hwnd
hDIB=Api_GetClipboardData(8) ;CF_DIB=8
Api_CloseClipboard()
EndIf
If Not hDIB ;if we didn't get a DIB, return a dummy image
himage=CreateImage(1,1)
Return himage
EndIf
pbmi=Api_GlobalLock(hDIB) ;lock memory and get pointer to it
btmp=CreateBank(40) ;initialize bank, we will resize it later
Api_RtlMoveMemory(btmp,pbmi,40) ;move info header to bank
sizeInfo=PeekInt(btmp,0) ;biSize
;calculate palette, Clipboard DIBs use the BITMAPINFO struct
sizePal=PeekInt(btmp,32) ;biClrUsed
If Not sizePal
If PeekShort(btmp,14)<16 ;no color table for 16/24/32
sizePal=1 Shl PeekShort(btmp,14) ;biBitCount, colors=2/16/256
Else
sizePal=PeekInt(btmp,16) ;biCompression, 16/32 use BI_BITFIELDS=3
EndIf
EndIf
sizePal=sizePal*4 ;sizeof(RGBQUAD)
width=PeekInt(btmp,4) ;biWidth
height=PeekInt(btmp,8) ;biHeight
bpp=PeekShort(btmp,14) ;biBitCount
bytespp=bpp/8 ;bytes per pixel
;calculate bits, DWORD-aligned scanline (Width * BitCount) * Height
sizeBits=((width*bpp+31)/32*4)*height
sizeDIB=sizeInfo+sizePal+sizeBits ;total size
ResizeBank btmp,sizeDIB ;resize bank to store DIB
Api_RtlMoveMemory(btmp,pbmi,sizeDIB) ;move DIB to bank
Api_GlobalUnlock(hDIB) ;unlock the DIB
himage=CreateImage(width,height) ;new image to write
;calculate DWORD-aligned offset of bits for proper alignment
;we'll use biSize to store each pixel, we don't need it any more
LockBuffer(ImageBuffer(himage))
For y=0 To height-1
offset=((width*bpp+31)/32*4)*y+sizeInfo+sizePal ;start of next scanline
For x=0 To width-1
If bpp=1
index=PeekByte(btmp,offset+(x/8)) ;1-bit, looks nasty but it works
;work out the bit, invert it, bitmask the byte and convert to 0/1
index=(index And (1 Shl (7-(x Mod 8)))) Shr (7-(x Mod 8))
EndIf
If bpp=4
index=PeekByte(btmp,offset+(x/2)) ;4-bit, work out the nibble
If x Mod 2 Then index=index And 15 ;get bits 0-3
If Not x Mod 2 Then index=index Shr 4 ;get bits 4-7
EndIf
If bpp=8
index=PeekByte(btmp,offset+x) ;8-bit, we have our index
EndIf
If bpp=24 Or bpp=32 ;get rgb offset
PokeByte btmp,0,PeekByte(btmp,offset+(x*bytespp)) ;blue
PokeByte btmp,1,PeekByte(btmp,offset+(x*bytespp)+1) ;green
PokeByte btmp,2,PeekByte(btmp,offset+(x*bytespp)+2) ;red
ElseIf bpp=16 ;rgb=565
PokeByte btmp,0,(PeekShort(btmp,offset+(x*bytespp)) And 31) Shl 3 ;blue
PokeByte btmp,1,((PeekShort(btmp,offset+(x*bytespp)) And 2016) Shr 5) Shl 2 ;green
PokeByte btmp,2,((PeekShort(btmp,offset+(x*bytespp)) And 63488) Shr 11) Shl 3 ;red
Else ;get palette index, 1/4/8-bit
PokeByte btmp,0,PeekInt(btmp,sizeInfo+(index*4))
PokeByte btmp,1,PeekInt(btmp,sizeInfo+(index*4)+1)
PokeByte btmp,2,PeekInt(btmp,sizeInfo+(index*4)+2)
EndIf
WritePixelFast x,height-1-y,PeekInt(btmp,0),ImageBuffer(himage) ;biSize
Next
Next
UnlockBuffer(ImageBuffer(himage))
FreeBank btmp
Return himage ;image handle
End Function