| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- Strict
- Rem
- bbdoc: Graphics/PNG loader
- about:
- The PNG loader module provides the ability to load PNG format #pixmaps.
- End Rem
- Module BRL.PNGLoader
- ModuleInfo "Version: 1.04"
- ModuleInfo "Author: Mark Sibly"
- ModuleInfo "License: zlib/libpng"
- ModuleInfo "Copyright: Blitz Research Ltd"
- ModuleInfo "Modserver: BRL"
- ModuleInfo "History: 1.04"
- ModuleInfo "History: libpng update to 1.2.12."
- ModuleInfo "History: Extra load error handling."
- ModuleInfo "History: 1.03 Release"
- ModuleInfo "History: Added Gray/Alpha support"
- ModuleInfo "History: 1.02 Release"
- ModuleInfo "History: Fixed palettized/grayscale support"
- Import BRL.Pixmap
- Import Pub.LibPNG
- Private
- Global png_stream:TStream
- Function png_read_fn( png_ptr,buf:Byte Ptr,size )
- Return png_stream.ReadBytes( buf,size )
- End Function
- Function png_write_fn( png_ptr,buf:Byte Ptr,size )
- Return png_stream.WriteBytes( buf,size )
- End Function
- Function png_flush_fn( png_ptr )
- png_stream.Flush
- End Function
- Public
- Rem
- bbdoc: Load a Pixmap in PNG format
- about:
- #LoadPixmapPNG loads a pixmap from @url in PNG format.
- If the pixmap cannot be loaded, Null is returned.
- End Rem
- Function LoadPixmapPNG:TPixmap( url:Object )
- png_stream=ReadStream( url )
- If Not png_stream Return
- Local buf:Byte[8]
-
- If png_stream.ReadBytes( buf,8 )<>8 Or png_sig_cmp( buf,0,8 )<>0
- png_stream.Close
- png_stream=Null
- Return
- EndIf
-
- Try
- Local png_ptr=png_create_read_struct( "1.2.12",Null,Null,Null )
-
- ' check for valid png_ptr
- If Not png_ptr Then
- png_stream.Close
- png_stream=Null
- Return
- End If
-
- Local info_ptr=png_create_info_struct( png_ptr )
-
- ' check for valid info_ptr
- If Not info_ptr Then
- png_stream.Close
- png_stream=Null
- png_destroy_read_struct Varptr png_ptr,Null,Null
- Return
- End If
-
- png_set_sig_bytes png_ptr,8
-
- png_set_read_fn png_ptr,Null,png_read_fn
-
- png_read_png png_ptr,info_ptr,PNG_TRANSFORM_EXPAND|PNG_TRANSFORM_STRIP_16,0
-
- Local width,height,bit_depth,color_type,interlace_type,compression_type,filter_method
- png_get_IHDR png_ptr,info_ptr,width,height,bit_depth,color_type,interlace_type,compression_type,filter_method
-
- Local pixmap:TPixmap
-
- If bit_depth=8
- Local pf
- Select color_type
- Case PNG_COLOR_TYPE_GRAY
- pf=PF_I8
- Case PNG_COLOR_TYPE_RGB
- pf=PF_RGB888
- Case PNG_COLOR_TYPE_RGBA
- pf=PF_RGBA8888
- Case PNG_COLOR_TYPE_GRAY_ALPHA
- pixmap=CreatePixmap( width,height,PF_RGBA8888 )
- Local rows:Byte Ptr Ptr=png_get_rows( png_ptr,info_ptr )
- For Local y=0 Until height
- Local src:Byte Ptr=rows[y]
- Local dst:Byte Ptr=pixmap.PixelPtr(0,y)
- For Local x=0 Until width
- Local a=src[0]
- Local i=src[1]
- dst[0]=i
- dst[1]=i
- dst[2]=i
- dst[3]=a
- src:+2
- dst:+4
- Next
- Next
- End Select
- If pf
- pixmap=CreatePixmap( width,height,pf )
- Local rows:Byte Ptr Ptr=png_get_rows( png_ptr,info_ptr )
- For Local y=0 Until height
- CopyPixels rows[y],pixmap.PixelPtr(0,y),pf,width
- Next
- EndIf
- EndIf
-
- png_destroy_read_struct Varptr png_ptr,Varptr info_ptr,Null
-
- png_stream.Close
- png_stream=Null
- Return pixmap
-
- Catch ex:String
-
- If ex<>"PNG ERROR" Throw ex
-
- End Try
- End Function
- Rem
- bbdoc: Save a Pixmap in PNG format
- about:
- #SavePixmapPNG saves @pixmap to @url in PNG format. If successful, #SavePixmapPNG returns
- True, otherwise False.
- The optional @compression parameter should be in the range 0 to 9, where
- 0 indicates no compression (fastest) and 9 indicates full compression (slowest).
- End Rem
- Function SavePixmapPNG( pixmap:TPixmap,url:Object,compression=5 )
- compression=Min( Max( compression,0 ),9 )
- png_stream:TStream=WriteStream( url )
- If Not png_stream Return
-
- Try
- Local png_ptr=png_create_write_struct( "1.2.12",Null,Null,Null )
- Local info_ptr=png_create_info_struct( png_ptr )
-
- png_set_write_fn png_ptr,Null,png_write_fn,png_flush_fn
-
- Local bitdepth,colortype,transform
-
- Select pixmap.format
- Case PF_I8
- colortype=PNG_COLOR_TYPE_GRAY
- Case PF_RGB888
- colortype=PNG_COLOR_TYPE_RGB
- Case PF_BGR888
- colortype=PNG_COLOR_TYPE_RGB
- transform=PNG_TRANSFORM_BGR
- Case PF_RGBA8888
- colortype=PNG_COLOR_TYPE_RGBA
- Case PF_BGRA8888
- colortype=PNG_COLOR_TYPE_RGBA
- transform=PNG_TRANSFORM_BGR
- Default
- colortype=PNG_COLOR_TYPE_RGBA
- pixmap=pixmap.Convert( PF_RGBA8888 )
- End Select
-
- png_set_compression_level png_ptr,compression
-
- png_set_IHDR png_ptr,info_ptr,pixmap.width,pixmap.height,8,colortype,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT
-
- Local rows:Byte Ptr[pixmap.height]
- For Local i=0 Until pixmap.height
- rows[i]=pixmap.PixelPtr( 0,i )
- Next
-
- png_set_rows png_ptr,info_ptr,rows
-
- png_write_png png_ptr,info_ptr,transform,Null
-
- png_destroy_write_struct Varptr png_ptr,Varptr info_ptr,Null
-
- png_stream.Close
- png_stream=Null
-
- Return True
-
- Catch ex:String
-
- If ex<>"PNG ERROR" Throw ex
-
- End Try
-
- End Function
- Private
- Type TPixmapLoaderPNG Extends TPixmapLoader
- Method LoadPixmap:TPixmap( stream:TStream )
-
- Return LoadPixmapPNG( stream )
-
- End Method
-
- End Type
- New TPixmapLoaderPNG
|