123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- SuperStrict
- Rem
- bbdoc: Image/TGA loader
- about:
- The TGA loader module provides the ability to load TGA format #pixmaps.
- End Rem
- Module Image.TGA
- ModuleInfo "Version: 1.08"
- ModuleInfo "Author: Simon Armstrong"
- ModuleInfo "License: zlib/libpng"
- ModuleInfo "Copyright: Blitz Research Ltd"
- ModuleInfo "Modserver: BRL"
- ModuleInfo "History: 1.08"
- ModuleInfo "History: Moved to Image namespace"
- ModuleInfo "History: 1.07 Release"
- ModuleInfo "History: Fixed memory error due to pointer based array reference"
- ModuleInfo "History: 1.06 Release"
- ModuleInfo "History: Support for Run Length Encoded compression"
- ModuleInfo "History: 1.05 Release"
- ModuleInfo "History: Fixed 24 bit byte ordering"
- Import BRL.Pixmap
- Import BRL.EndianStream
- Const TGA_NULL:Int=0
- Const TGA_MAP:Int=1
- Const TGA_RGB:Int=2
- Const TGA_MONO:Int=3
- Const TGA_RLEMAP:Int=9
- Const TGA_RLERGB:Int=10
- Const TGA_RLEMONO:Int=11
- Const TGA_COMPMAP:Int=32
- Const TGA_COMPMAP4:Int=33
- Type tgahdr
- Field idlen:Byte,colourmaptype:Byte,imgtype:Byte,indexlo:Byte,indexhi:Byte,lenlo:Byte,lenhi:Byte,cosize:Byte
- Field x0:Short,y0:Short,width:Short,height:Short
- Field psize:Byte,attbits:Byte
- End Type
- Function makeargb:Int(a:Int,r:Int,g:Int,b:Int)
- '?BigEndian
- ' Return (b Shl 24)|(g Shl 16)|(r Shl 8)|a
- '?
- Return (a Shl 24)|(r Shl 16)|(g Shl 8)|b
- End Function
- Type TPixmapLoaderTGA Extends TPixmapLoader
- Method LoadPixmap:TPixmap( stream:TStream )
- Local hdr:tgahdr
- Local w:Int,h:Int,tgatype:Int,bits:Int
- Local buffer:Int[]
- Local sbuffer:Short[]
- Local bbuffer:Byte[]
- Local i:Int,x:Int,y:Int,t:Int,a:Int
- Local pixmap:TPixmap
-
- stream=LittleEndianStream( stream )
- hdr=New tgahdr
- If stream.ReadBytes( hdr,8 )<>8 Return Null
- hdr.x0=stream.ReadShort()
- hdr.y0=stream.ReadShort()
- hdr.width=stream.ReadShort()
- hdr.height=stream.ReadShort()
- hdr.psize=stream.ReadByte()
- hdr.attbits=stream.ReadByte()
- bits=hdr.psize
- w=hdr.width
- h=hdr.height
- tgatype=hdr.imgtype
- If hdr.colourmaptype Return Null
- If Not (tgatype=TGA_MAP Or tgatype=TGA_RGB Or tgatype=TGA_RLERGB) Return Null
- If Not (bits=15 Or bits=16 Or bits=24 Or bits=32) Return Null
- If w<1 Or w>4096 Return Null
- If h<1 Or h>4096 Return Null
- If bits=16 Or bits=32
- pixmap=CreatePixmap( w,h,PF_RGBA8888)
- Else
- pixmap=CreatePixmap( w,h,PF_RGB888)
- EndIf
- For i=1 To hdr.idlen
- stream.ReadByte
- Next
- buffer=New Int[w]
- bbuffer=New Byte[w*3]
- Select tgatype
- Case TGA_RGB
- For y=h-1 To 0 Step -1
- Select bits
- Case 15
- For x=0 Until w
- t=stream.ReadShort()
- buffer[x]=makeargb(255,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
- Next
- Case 16
- For x=0 Until w
- t=stream.ReadShort()
- a=255
- If (t&$8000) a=0
- buffer[x]=makeargb(a,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
- Next
- Case 24
- stream.readbytes(bbuffer,w*3)
- For x=0 Until w
- buffer[x]=makeargb(255,bbuffer[x*3+2],bbuffer[x*3+1],bbuffer[x*3+0])
- Next
- Case 32
- stream.readbytes(buffer,w*4)
- End Select
- ConvertPixels(buffer,PF_BGRA8888,pixmap.pixelptr(0,y),pixmap.format,w)
- Next
- Case TGA_RLERGB
- Local n:Int,argb:Int
- For y=h-1 To 0 Step -1
- x=0
- Select bits
- Case 15
- While x<w
- n=stream.ReadByte()
- If n&128
- n:-127
- t=stream.ReadShort()
- argb=makeargb(255,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
- While n
- buffer[x]=argb
- n:-1
- x:+1
- Wend
- Else
- n:+1
- For i=0 Until n
- t=stream.ReadShort()
- buffer[x]=makeargb(255,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
- x:+1
- Next
- EndIf
- Wend
- Case 16
- While x<w
- n=stream.ReadByte()
- If n&128
- n:-127
- t=stream.ReadShort()
- a=255
- If (t&$8000) a=0
- argb=makeargb(a,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
- While n
- buffer[x]=argb
- n:-1
- x:+1
- Wend
- Else
- n:+1
- For i=0 Until n
- t=stream.ReadShort()
- a=255
- If (t&$8000) a=0
- buffer[x]=makeargb(a,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
- x:+1
- Next
- EndIf
- Wend
- Case 24
- While x<w
- n=stream.ReadByte()
- If n&128
- n:-127
- stream.readbytes bbuffer,3
- argb=makeargb(255,bbuffer[2],bbuffer[1],bbuffer[0])
- While n
- buffer[x]=argb
- n:-1
- x:+1
- Wend
- Else
- n:+1
- stream.readbytes(bbuffer,n*3)
- For i=0 Until n
- buffer[x]=makeargb(255,bbuffer[i*3+2],bbuffer[i*3+1],bbuffer[i*3+0])
- x:+1
- Next
- EndIf
- Wend
- Case 32
- While x<w
- n=stream.ReadByte()
- If n&128
- n:-127
- stream.readbytes Varptr argb,4
- While n
- buffer[x]=argb
- n:-1
- x:+1
- Wend
- Else
- n:+1
- stream.readbytes(Byte Ptr(buffer)+x*4,n*4)
- x:+n
- EndIf
- Wend
- End Select
- ConvertPixels(buffer,PF_BGRA8888,pixmap.pixelptr(0,y),pixmap.format,w)
- Next
- End Select
-
- Return pixmap
-
- End Method
- End Type
- New TPixmapLoaderTGA
|