jxl.bmx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. '
  2. ' Copyright (c) 2022 Bruce A Henderson
  3. ' All rights reserved.
  4. '
  5. ' Redistribution and use in source and binary forms, with or without
  6. ' modification, are permitted provided that the following conditions are met:
  7. ' * Redistributions of source code must retain the above copyright
  8. ' notice, this list of conditions and the following disclaimer.
  9. ' * Redistributions in binary form must reproduce the above copyright
  10. ' notice, this list of conditions and the following disclaimer in the
  11. ' documentation and/or other materials provided with the distribution.
  12. ' * Neither the name of the author nor the
  13. ' names of its contributors may be used to endorse or promote products
  14. ' derived from this software without specific prior written permission.
  15. '
  16. ' THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY
  17. ' EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. ' WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. ' DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  20. ' DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. ' (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. ' LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. ' ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. ' (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. ' SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. '
  27. SuperStrict
  28. Rem
  29. bbdoc: Image/JXL loader
  30. about:
  31. The JXL loader module provides the ability to load JXL format #pixmaps.
  32. End Rem
  33. Module Image.JXL
  34. ModuleInfo "Version: 1.00"
  35. ModuleInfo "License: BSD"
  36. ModuleInfo "Copyright: Wrapper - 2022 Bruce A Henderson"
  37. ModuleInfo "History: 1.00"
  38. ModuleInfo "History: Initial Release."
  39. ModuleInfo "CPP_OPTS: -std=c++11 -D__STDC_FORMAT_MACROS"
  40. ModuleInfo "C_OPTS: -std=c99"
  41. ModuleInfo "CC_OPTS: -DJPEGXL_MAJOR_VERSION=0"
  42. ModuleInfo "CC_OPTS: -DJPEGXL_MINOR_VERSION=7"
  43. ModuleInfo "CC_OPTS: -DJPEGXL_PATCH_VERSION=0"
  44. ?ptr64
  45. Import "common.bmx"
  46. Rem
  47. bbdoc: Number of threads to use during Jxl decoding.
  48. about: The default is to use only the current thread.
  49. End Rem
  50. Global JxlDecoderThreadCount:Int = 0
  51. Private
  52. Type TPixmapLoaderJXL Extends TPixmapLoader
  53. Method LoadPixmap:TPixmap( stream:TStream ) Override
  54. Local data:Byte[] = LoadByteArray(stream)
  55. If data Then
  56. Local sig:EJxlSignature = JxlSignatureCheck(data, Size_T(data.Length))
  57. If sig = EJxlSignature.JXL_SIG_NOT_ENOUGH_BYTES Or sig = EJxlSignature.JXL_SIG_INVALID Then
  58. Return Null
  59. End If
  60. Local decoder:TJxlDecoder = New TJxlDecoder()
  61. Local pix:TPixmap = decoder.Load(data)
  62. Return pix
  63. End If
  64. End Method
  65. End Type
  66. Type TJxlDecoder
  67. Field decoderPtr:Byte Ptr
  68. Field runnerPtr:Byte Ptr
  69. Method New()
  70. decoderPtr = JxlDecoderCreate(Null)
  71. End Method
  72. Method Load:TPixmap(data:Byte[])
  73. Local pix:TPixmap
  74. Local status:Int = JxlDecoderSubscribeEvents(decoderPtr, JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE)
  75. If status <> JXL_DEC_SUCCESS Then
  76. Return Null
  77. End If
  78. runnerPtr = JxlResizableParallelRunnerCreate(Null)
  79. JxlResizableParallelRunnerSetThreads(runnerPtr, Size_T(Max(0, JxlDecoderThreadCount)))
  80. If bmx_jxl_JxlDecoderSetParallelRunner(decoderPtr, runnerPtr) <> JXL_DEC_SUCCESS Then
  81. Return Null
  82. End If
  83. Local info:SJxlBasicInfo
  84. Local format:SJxlPixelFormat = New SJxlPixelFormat(4, EJxlDataType.JXL_TYPE_UINT8, EJxlEndianness.JXL_BIG_ENDIAN, 4)
  85. Local pixFormat:Int = PF_RGBA8888
  86. Local width:Int
  87. Local height:Int
  88. JxlDecoderSetInput(decoderPtr, data, Size_T(data.Length))
  89. JxlDecoderCloseInput(decoderPtr)
  90. While True
  91. status = JxlDecoderProcessInput(decoderPtr)
  92. If status = JXL_DEC_ERROR Then
  93. Return Null
  94. Else If status = JXL_DEC_NEED_MORE_INPUT Then
  95. Return Null
  96. Else If status = JXL_DEC_BASIC_INFO Then
  97. If JxlDecoderGetBasicInfo(decoderPtr, info) <> JXL_DEC_SUCCESS Then
  98. Return Null
  99. End If
  100. width = info.xsize
  101. height = info.ysize
  102. If info.alpha_bits = 0 Then
  103. format.num_channels = 3
  104. format.align = 4
  105. pixFormat = PF_RGB888
  106. End If
  107. pix = TPixmap.Create(width, height, pixFormat, Int(format.align))
  108. Else If status = JXL_DEC_NEED_IMAGE_OUT_BUFFER Then
  109. Local bufferSize:Size_T
  110. If JxlDecoderImageOutBufferSize(decoderPtr, format, bufferSize) <> JXL_DEC_SUCCESS Then
  111. Return Null
  112. End If
  113. If JxlDecoderSetImageOutBuffer(decoderPtr, format, pix.pixels, Size_T(pix.capacity)) <> JXL_DEC_SUCCESS Then
  114. Return Null
  115. End If
  116. Else If status = JXL_DEC_FULL_IMAGE Then
  117. Exit
  118. Else If status = JXL_DEC_SUCCESS Then
  119. Exit
  120. Else
  121. Return Null
  122. End If
  123. Wend
  124. Return pix
  125. End Method
  126. Method Free()
  127. If runnerPtr Then
  128. JxlResizableParallelRunnerDestroy(runnerPtr)
  129. runnerPtr = Null
  130. End If
  131. If decoderPtr Then
  132. JxlDecoderDestroy(decoderPtr)
  133. decoderPtr = Null
  134. End If
  135. End Method
  136. Method Delete()
  137. Free()
  138. End Method
  139. End Type
  140. New TPixmapLoaderJXL
  141. ?