Any one know how to convert a 12bpp memory buffer (from windows API) into a tPixMap object?
For 8/24/32 BPP would use CreateStaticPixmap(e.g. TempMap= CreateStaticPixmap (MemoryAdress, Width, Height, Width,PF_A8) )
12 bits per pixel, you're saying?
So each component is 4 bits?
First find out if the pixmap has a `pitch`, ie if you need to skip at the end of each row.
Then you can set up a simple loop to go through the source data. Use a byte pointer and read 2 pixels at a time, then use AND's to isolate specific bits and shifts to move them and OR's to combine them. Make each component end up in a separate variable. Then write them out to the pixmap. You can write using a byte pointer, even if the data is stored in int's.
Something like..
'Assumes the pixmap is RGBA format
Local Source:Int Ptr=Memory 'the address of the 12bpp data
Local Dest:Byte Ptr=PixmapPtr(pixmap) 'your pixmap object
Local Width:Int=PixmapWidth(pixmap)
Local Diff:Int=PixmapPitch(pixmap)-Width
Local Pixel,Red,Green,Blue,Alpha:Int
Alpha=1
For Local Y:Int=0 to PixmapHeight(pixmap)-1
For Local X:Int=0 to (PixmapWidth/8)-1 Step 2
Pixel=Source[x]
Dest[x]=(Pixel & $F0000000) Shr 28
Dest[x+1]=(Pixel & $0F000000) Shr 24
Dest[x+2]=(Pixel & $00F00000) Shr 20
Dest[x+3]=Alpha
Dest[x+4]=(Pixel & $000F0000) Shr 16
Dest[x+5]=(Pixel & $0000F000) Shr 12
Dest[x+6]=(Pixel & $00000F00) Shr 8
Dest[x+7]=Alpha
'etc
I guess you'd need to read in 4 whole 12bpp pixels because each is 1.5 bytes, so 2 would be 3 bytes, you could maybe work with 6 bytes ie 4 source pixels at a time, but not easily. Maybe better with 8 source pixels, 12 bytes, handle them as 3 int's.
Thanks Angel
The conversion is for a frame from a webcam.
Played around with it a bit an found that the format is 12bit YUV. I can get a image but the coluring is incorrect. I am attempting to convert the 4 bit YUV values to 8 Bit RGB values (RGB888)
Any ideas?
Code Below:-
TempMap= CreatePixmap (width, Height,PF_RGB888)
Local bnkPixels=CreateStaticBank(VideoMemoryAdress,width*Height*1.5)
' Local bnkTemp=CreateBank(width*Height*3)
'Assumes the pixmap is RGB format
Local sourcep:Byte Ptr=VideoMemoryAdress 'the address of the 12bpp YUV data
Local Dest:Byte Ptr= PixmapPixelPtr(tempmap,0,0) 'your pixmap object
Local Byte1:Byte
Local y1,u1,v1:Int
Local r,g,b :Int
Local YUV:Byte[width*3,Height]
'Transfer into Array(W*H) (YUV in matrices of 3 widths for Y,U and V) - i.e
For Local N:Int = 0 To Height -1
For Local n1:Int = 0 To (width*1.5)-1
Byte1=sourcep[(N*width)+n1]
yuv[(n1*2),N]=(Byte1 &$0F) Shr 4
yuv[(n1*2)+1,n]=(Byte1 & $F0)
Next
Next
Local Off1:Int=width 'start point for second set of values on row
Local Off2:Int=width*2 'start point for thrid set of values on row
For Local x:Int=0 To Height-1
For Local y:Int =0 To width-1
y1=yuv[y,x]
u1=yuv[OFF1+y,x]
u1=yuv[OFF2+y,x]
y1:-16
u1:-128
v1:-128
R = ( 298 * y1 + 409 * v1 + 128)& $ff
G = ( 298 * y1 - 100 * u1 - 208 * v1 + 128) & $ff
B = ( 298 * y1 + 516 * u1 + 128) & $ff
Dest[(((x*width)+y)*3)]=r
Dest[(((x*width)+y)*3)+1]=G
Dest[(((x*width)+y)*3)+2]=b
Next
Next
Hmm . I don't know anything about YUV format or how it's stored, but I'm sure there's plenty on the web about it to help you convert it to RGB.
K,
Thanks ... looked at this and used the Microsoft version but I think I am reading the bytes incorrectly.
I have updated the class to support 8bpp, 32 bpp and 12bpp YUV (typical for intel webcams).
The source can be found at
http://www.kita.org.uk/software.html