tga.bmx 5.4 KB

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