pngloader.bmx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. Strict
  2. Rem
  3. bbdoc: Graphics/PNG loader
  4. about:
  5. The PNG loader module provides the ability to load PNG format #pixmaps.
  6. End Rem
  7. Module BRL.PNGLoader
  8. ModuleInfo "Version: 1.04"
  9. ModuleInfo "Author: Mark Sibly"
  10. ModuleInfo "License: zlib/libpng"
  11. ModuleInfo "Copyright: Blitz Research Ltd"
  12. ModuleInfo "Modserver: BRL"
  13. ModuleInfo "History: 1.04"
  14. ModuleInfo "History: libpng update to 1.2.12."
  15. ModuleInfo "History: Extra load error handling."
  16. ModuleInfo "History: 1.03 Release"
  17. ModuleInfo "History: Added Gray/Alpha support"
  18. ModuleInfo "History: 1.02 Release"
  19. ModuleInfo "History: Fixed palettized/grayscale support"
  20. Import BRL.Pixmap
  21. Import Pub.LibPNG
  22. Private
  23. Global png_stream:TStream
  24. Function png_read_fn( png_ptr,buf:Byte Ptr,size )
  25. Return png_stream.ReadBytes( buf,size )
  26. End Function
  27. Function png_write_fn( png_ptr,buf:Byte Ptr,size )
  28. Return png_stream.WriteBytes( buf,size )
  29. End Function
  30. Function png_flush_fn( png_ptr )
  31. png_stream.Flush
  32. End Function
  33. Public
  34. Rem
  35. bbdoc: Load a Pixmap in PNG format
  36. about:
  37. #LoadPixmapPNG loads a pixmap from @url in PNG format.
  38. If the pixmap cannot be loaded, Null is returned.
  39. End Rem
  40. Function LoadPixmapPNG:TPixmap( url:Object )
  41. png_stream=ReadStream( url )
  42. If Not png_stream Return
  43. Local buf:Byte[8]
  44. If png_stream.ReadBytes( buf,8 )<>8 Or png_sig_cmp( buf,0,8 )<>0
  45. png_stream.Close
  46. png_stream=Null
  47. Return
  48. EndIf
  49. Try
  50. Local png_ptr=png_create_read_struct( "1.2.12",Null,Null,Null )
  51. ' check for valid png_ptr
  52. If Not png_ptr Then
  53. png_stream.Close
  54. png_stream=Null
  55. Return
  56. End If
  57. Local info_ptr=png_create_info_struct( png_ptr )
  58. ' check for valid info_ptr
  59. If Not info_ptr Then
  60. png_stream.Close
  61. png_stream=Null
  62. png_destroy_read_struct Varptr png_ptr,Null,Null
  63. Return
  64. End If
  65. png_set_sig_bytes png_ptr,8
  66. png_set_read_fn png_ptr,Null,png_read_fn
  67. png_read_png png_ptr,info_ptr,PNG_TRANSFORM_EXPAND|PNG_TRANSFORM_STRIP_16,0
  68. Local width,height,bit_depth,color_type,interlace_type,compression_type,filter_method
  69. png_get_IHDR png_ptr,info_ptr,width,height,bit_depth,color_type,interlace_type,compression_type,filter_method
  70. Local pixmap:TPixmap
  71. If bit_depth=8
  72. Local pf
  73. Select color_type
  74. Case PNG_COLOR_TYPE_GRAY
  75. pf=PF_I8
  76. Case PNG_COLOR_TYPE_RGB
  77. pf=PF_RGB888
  78. Case PNG_COLOR_TYPE_RGBA
  79. pf=PF_RGBA8888
  80. Case PNG_COLOR_TYPE_GRAY_ALPHA
  81. pixmap=CreatePixmap( width,height,PF_RGBA8888 )
  82. Local rows:Byte Ptr Ptr=png_get_rows( png_ptr,info_ptr )
  83. For Local y=0 Until height
  84. Local src:Byte Ptr=rows[y]
  85. Local dst:Byte Ptr=pixmap.PixelPtr(0,y)
  86. For Local x=0 Until width
  87. Local a=src[0]
  88. Local i=src[1]
  89. dst[0]=i
  90. dst[1]=i
  91. dst[2]=i
  92. dst[3]=a
  93. src:+2
  94. dst:+4
  95. Next
  96. Next
  97. End Select
  98. If pf
  99. pixmap=CreatePixmap( width,height,pf )
  100. Local rows:Byte Ptr Ptr=png_get_rows( png_ptr,info_ptr )
  101. For Local y=0 Until height
  102. CopyPixels rows[y],pixmap.PixelPtr(0,y),pf,width
  103. Next
  104. EndIf
  105. EndIf
  106. png_destroy_read_struct Varptr png_ptr,Varptr info_ptr,Null
  107. png_stream.Close
  108. png_stream=Null
  109. Return pixmap
  110. Catch ex:String
  111. If ex<>"PNG ERROR" Throw ex
  112. End Try
  113. End Function
  114. Rem
  115. bbdoc: Save a Pixmap in PNG format
  116. about:
  117. #SavePixmapPNG saves @pixmap to @url in PNG format. If successful, #SavePixmapPNG returns
  118. True, otherwise False.
  119. The optional @compression parameter should be in the range 0 to 9, where
  120. 0 indicates no compression (fastest) and 9 indicates full compression (slowest).
  121. End Rem
  122. Function SavePixmapPNG( pixmap:TPixmap,url:Object,compression=5 )
  123. compression=Min( Max( compression,0 ),9 )
  124. png_stream:TStream=WriteStream( url )
  125. If Not png_stream Return
  126. Try
  127. Local png_ptr=png_create_write_struct( "1.2.12",Null,Null,Null )
  128. Local info_ptr=png_create_info_struct( png_ptr )
  129. png_set_write_fn png_ptr,Null,png_write_fn,png_flush_fn
  130. Local bitdepth,colortype,transform
  131. Select pixmap.format
  132. Case PF_I8
  133. colortype=PNG_COLOR_TYPE_GRAY
  134. Case PF_RGB888
  135. colortype=PNG_COLOR_TYPE_RGB
  136. Case PF_BGR888
  137. colortype=PNG_COLOR_TYPE_RGB
  138. transform=PNG_TRANSFORM_BGR
  139. Case PF_RGBA8888
  140. colortype=PNG_COLOR_TYPE_RGBA
  141. Case PF_BGRA8888
  142. colortype=PNG_COLOR_TYPE_RGBA
  143. transform=PNG_TRANSFORM_BGR
  144. Default
  145. colortype=PNG_COLOR_TYPE_RGBA
  146. pixmap=pixmap.Convert( PF_RGBA8888 )
  147. End Select
  148. png_set_compression_level png_ptr,compression
  149. png_set_IHDR png_ptr,info_ptr,pixmap.width,pixmap.height,8,colortype,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT
  150. Local rows:Byte Ptr[pixmap.height]
  151. For Local i=0 Until pixmap.height
  152. rows[i]=pixmap.PixelPtr( 0,i )
  153. Next
  154. png_set_rows png_ptr,info_ptr,rows
  155. png_write_png png_ptr,info_ptr,transform,Null
  156. png_destroy_write_struct Varptr png_ptr,Varptr info_ptr,Null
  157. png_stream.Close
  158. png_stream=Null
  159. Return True
  160. Catch ex:String
  161. If ex<>"PNG ERROR" Throw ex
  162. End Try
  163. End Function
  164. Private
  165. Type TPixmapLoaderPNG Extends TPixmapLoader
  166. Method LoadPixmap:TPixmap( stream:TStream )
  167. Return LoadPixmapPNG( stream )
  168. End Method
  169. End Type
  170. New TPixmapLoaderPNG