I started PBXImage so I could learn image formats and image manipulation, but I always hit a snag. Haqibaba, seemingly a master at images, bailed me out with his amazing knowledge. Now, I have turned a new corner.
Alias/Wavefront .PIX format is now available for PB users. Kind of an newer-old format, HOWEVER, with my new knowledge, SGI graphics and their textures and bitmapped formats are a short ways away (hopefully). Knowing how to decode this format could possibly lead to decoding their multilayered image/texture format, which are stellar for game creation.
Please report any bugs. XNview can save .PIX, so you can test all kinds of bitmap conversion to .PIX with this loader.
Code: Select all
Structure APIXHEADER
;;;NO Magic number!!!!!!!!!!!!
width.w; /* Width of image in pixels */
height.w; /* Height of image in pixels */
XOffset.w; /* X of lower left corner of image */ NOT USED
YOffset.w; /* Y of lower left corner of image */ NOT USED
bpp.w ; ALWAYS 24
EndStructure
Macro SwapWord(val)
(((val >> 8) & $00FF) | ((val << 8) & $FF00))
EndMacro
Procedure.l Endian(val.l)
!MOV Eax,dword[p.v_val]
!BSWAP Eax
ProcedureReturn
EndProcedure
Procedure LoadPix(filename.s)
file=ReadFile(#PB_Any,filename)
If file
;really simple header
*PIX.APIXHEADER=AllocateMemory(SizeOf(APIXHEADER))
ReadData(file,*PIX.APIXHEADER,SizeOf(APIXHEADER))
width=SwapWord(*PIX\width)
height=SwapWord(*PIX\height)
bpp= SwapWord(*PIX\bpp)
If bpp =24
pitch=(((width*bpp)+31)/32)*4 ;DWORD-aligned width
bhsize=SizeOf(BITMAPINFOHEADER) ;DIB info header size
ncolors=0
;create the bitmap structure
hDIB=AllocateMemory(bhsize+(ncolors*4)+(pitch*height))
Protected bmpinfo.BITMAPINFOHEADER
With bmpinfo
\biSize=SizeOf(BITMAPINFOHEADER) ;Size of struct
\biWidth=width ;Bitmap width
\biHeight=-height ;Bitmap height, bitmap is top down
\biPlanes=1 ;Single plane
\biBitCount=24 ;Bit depth
\biCompression=#BI_RGB ;No compression
\biSizeImage=0
\biXPelsPerMeter=0
\biYPelsPerMeter=0
\biClrUsed=0
\biClrImportant=0
EndWith
Bits=hDIB+SizeOf(BITMAPINFOHEADER) ;Pointer to bits
For a=0 To height-1
LineBytesRead=0
While LineBytesRead<pitch-2
If Not Eof(file); protect ourselves from overflow
lng.l=Endian(ReadLong(file)); byte order is reversed in .PIX
Blue.b=PeekB(@lng) &255;blue
Green.b=PeekB(@lng+1) &255 ;green
Red.b= PeekB(@lng+2)&255 ;red
runcnt.b= PeekB(@lng+3);&255;runcount
For b=0 To (runcnt&$FF)-1
;PokeL(Bits+LineBytesRead+3+(a*pitch),RGB(Red,Green,Blue)) ;i think this also works - but not as good
PokeB(Bits+LineBytesRead+(a*pitch),Red)
PokeB(Bits+LineBytesRead+1+(a*pitch),Green)
PokeB(Bits+LineBytesRead+2+(a*pitch),Blue)
LineBytesRead=LineBytesRead+3
Next
Else
Break
EndIf
Wend
Next
CloseFile(file)
Else
ProcedureReturn -1
EndIf
;Create the DDB bitmap
hdc=GetDC_(#Null)
hBitmap=CreateDIBitmap_(hdc,bmpinfo,#CBM_INIT,Bits,bmpinfo,#DIB_RGB_COLORS)
FreeMemory(*PIX.APIXHEADER)
FreeMemory(hDIB)
ProcedureReturn hBitmap
Else
ProcedureReturn -1
EndIf
EndProcedure
If OpenWindow(0,0,0,670,620,"Load PIX",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ButtonGadget(0, 10, 10,80,20,"Open File")
ImageGadget(1, 10, 50, 300,300,0,#PB_Image_Border)
EndIf
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case 0
Pattern$="All Supported Formats|*.pix"
filename.s=OpenFileRequester("Choose An Image File To Open","",Pattern$,0)
If filename
hBitmap=LoadPix(filename.s)
SendMessage_(GadgetID(1), #STM_SETIMAGE,#IMAGE_BITMAP,hBitmap)
EndIf
EndSelect
Case #PB_Event_CloseWindow
End
EndSelect
ForEver