12bpp -> tPixMap

BlitzMax Forums/BlitzMax Programming/12bpp -> tPixMap

MarkAM(Posted 2006) [#1]
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) )


ImaginaryHuman(Posted 2006) [#2]
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.


ImaginaryHuman(Posted 2006) [#3]
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.


MarkAM(Posted 2006) [#4]
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


ImaginaryHuman(Posted 2006) [#5]
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.


Regular K(Posted 2006) [#6]
http://en.wikipedia.org/wiki/YUV

Might help


MarkAM(Posted 2006) [#7]
K,

Thanks ... looked at this and used the Microsoft version but I think I am reading the bytes incorrectly.


MarkAM(Posted 2006) [#8]
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