tgaloader.bmx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. Strict
  2. Rem
  3. bbdoc: Graphics/TGA loader
  4. about:
  5. The TGA loader module provides the ability to load TGA format #pixmaps.
  6. End Rem
  7. Module BRL.TGALoader
  8. ModuleInfo "Version: 1.07"
  9. ModuleInfo "Author: Simon Armstrong"
  10. ModuleInfo "License: zlib/libpng"
  11. ModuleInfo "Copyright: Blitz Research Ltd"
  12. ModuleInfo "Modserver: BRL"
  13. ModuleInfo "History: 1.07 Release"
  14. ModuleInfo "History: Fixed memory error due to pointer based array reference"
  15. ModuleInfo "History: 1.06 Release"
  16. ModuleInfo "History: Support for Run Length Encoded compression"
  17. ModuleInfo "History: 1.05 Release"
  18. ModuleInfo "History: Fixed 24 bit byte ordering"
  19. Import BRL.Pixmap
  20. Import BRL.EndianStream
  21. Const TGA_NULL=0
  22. Const TGA_MAP=1
  23. Const TGA_RGB=2
  24. Const TGA_MONO=3
  25. Const TGA_RLEMAP=9
  26. Const TGA_RLERGB=10
  27. Const TGA_RLEMONO=11
  28. Const TGA_COMPMAP=32
  29. Const TGA_COMPMAP4=33
  30. Type tgahdr
  31. Field idlen:Byte,colourmaptype:Byte,imgtype:Byte,indexlo:Byte,indexhi:Byte,lenlo:Byte,lenhi:Byte,cosize:Byte
  32. Field x0:Short,y0:Short,width:Short,height:Short
  33. Field psize:Byte,attbits:Byte
  34. End Type
  35. Function makeargb(a,r,g,b)
  36. ?BigEndian
  37. Return (b Shl 24)|(g Shl 16)|(r Shl 8)|a
  38. ?
  39. Return (a Shl 24)|(r Shl 16)|(g Shl 8)|b
  40. End Function
  41. Type TPixmapLoaderTGA Extends TPixmapLoader
  42. Method LoadPixmap:TPixmap( stream:TStream )
  43. Local hdr:tgahdr
  44. Local w,h,tgatype,bits
  45. Local buffer[]
  46. Local sbuffer:Short[]
  47. Local bbuffer:Byte[]
  48. Local i,x,y,t,a
  49. Local pixmap:TPixmap
  50. stream=LittleEndianStream( stream )
  51. hdr=New tgahdr
  52. If stream.ReadBytes( hdr,8 )<>8 Return Null
  53. hdr.x0=stream.ReadShort()
  54. hdr.y0=stream.ReadShort()
  55. hdr.width=stream.ReadShort()
  56. hdr.height=stream.ReadShort()
  57. hdr.psize=stream.ReadByte()
  58. hdr.attbits=stream.ReadByte()
  59. bits=hdr.psize
  60. w=hdr.width
  61. h=hdr.height
  62. tgatype=hdr.imgtype
  63. If hdr.colourmaptype Return Null
  64. If Not (tgatype=TGA_MAP Or tgatype=TGA_RGB Or tgatype=TGA_RLERGB) Return Null
  65. If Not (bits=15 Or bits=16 Or bits=24 Or bits=32) Return Null
  66. If w<1 Or w>4096 Return Null
  67. If h<1 Or h>4096 Return Null
  68. If bits=16 Or bits=32
  69. pixmap=CreatePixmap( w,h,PF_RGBA8888)
  70. Else
  71. pixmap=CreatePixmap( w,h,PF_RGB888)
  72. EndIf
  73. For i=1 To hdr.idlen
  74. stream.ReadByte
  75. Next
  76. buffer=New Int[w]
  77. bbuffer=New Byte[w*3]
  78. Select tgatype
  79. Case TGA_RGB
  80. For y=h-1 To 0 Step -1
  81. Select bits
  82. Case 15
  83. For x=0 Until w
  84. t=stream.ReadShort()
  85. buffer[x]=makeargb(255,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
  86. Next
  87. Case 16
  88. For x=0 Until w
  89. t=stream.ReadShort()
  90. a=255
  91. If (t&$8000) a=0
  92. buffer[x]=makeargb(a,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
  93. Next
  94. Case 24
  95. stream.readbytes(bbuffer,w*3)
  96. For x=0 Until w
  97. buffer[x]=makeargb(255,bbuffer[x*3+2],bbuffer[x*3+1],bbuffer[x*3+0])
  98. Next
  99. Case 32
  100. stream.readbytes(buffer,w*4)
  101. End Select
  102. ConvertPixels(buffer,PF_BGRA8888,pixmap.pixelptr(0,y),pixmap.format,w)
  103. Next
  104. Case TGA_RLERGB
  105. Local n,argb
  106. For y=h-1 To 0 Step -1
  107. x=0
  108. Select bits
  109. Case 15
  110. While x<w
  111. n=stream.ReadByte()
  112. If n&128
  113. n:-127
  114. t=stream.ReadShort()
  115. argb=makeargb(255,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
  116. While n
  117. buffer[x]=argb
  118. n:-1
  119. x:+1
  120. Wend
  121. Else
  122. n:+1
  123. For i=0 Until n
  124. t=stream.ReadShort()
  125. buffer[x]=makeargb(255,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
  126. x:+1
  127. Next
  128. EndIf
  129. Wend
  130. Case 16
  131. While x<w
  132. n=stream.ReadByte()
  133. If n&128
  134. n:-127
  135. t=stream.ReadShort()
  136. a=255
  137. If (t&$8000) a=0
  138. argb=makeargb(a,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
  139. While n
  140. buffer[x]=argb
  141. n:-1
  142. x:+1
  143. Wend
  144. Else
  145. n:+1
  146. For i=0 Until n
  147. t=stream.ReadShort()
  148. a=255
  149. If (t&$8000) a=0
  150. buffer[x]=makeargb(a,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8)
  151. x:+1
  152. Next
  153. EndIf
  154. Wend
  155. Case 24
  156. While x<w
  157. n=stream.ReadByte()
  158. If n&128
  159. n:-127
  160. stream.readbytes bbuffer,3
  161. argb=makeargb(255,bbuffer[2],bbuffer[1],bbuffer[0])
  162. While n
  163. buffer[x]=argb
  164. n:-1
  165. x:+1
  166. Wend
  167. Else
  168. n:+1
  169. stream.readbytes(bbuffer,n*3)
  170. For i=0 Until n
  171. buffer[x]=makeargb(255,bbuffer[i*3+2],bbuffer[i*3+1],bbuffer[i*3+0])
  172. x:+1
  173. Next
  174. EndIf
  175. Wend
  176. Case 32
  177. While x<w
  178. n=stream.ReadByte()
  179. If n&128
  180. n:-127
  181. stream.readbytes Varptr argb,4
  182. While n
  183. buffer[x]=argb
  184. n:-1
  185. x:+1
  186. Wend
  187. Else
  188. n:+1
  189. stream.readbytes(Byte Ptr(buffer)+x*4,n*4)
  190. x:+n
  191. EndIf
  192. Wend
  193. End Select
  194. ConvertPixels(buffer,PF_BGRA8888,pixmap.pixelptr(0,y),pixmap.format,w)
  195. Next
  196. End Select
  197. Return pixmap
  198. End Method
  199. End Type
  200. New TPixmapLoaderTGA