1- const uint8ArrayUtf8ByteString = ( array , start , end ) => {
1+ import type libheifType from 'libheif-js/wasm-bundle.js' ;
2+ import type { HeifImage } from 'libheif-js/wasm-bundle.js' ;
3+
4+ const uint8ArrayUtf8ByteString = ( array : Uint8Array , start : number , end : number ) => {
25 return String . fromCharCode ( ...array . slice ( start , end ) ) ;
36} ;
47
58// brands explained: https://github.com/strukturag/libheif/issues/83
69// code adapted from: https://github.com/sindresorhus/file-type/blob/6f901bd82b849a85ca4ddba9c9a4baacece63d31/core.js#L428-L438
7- const isHeic = ( buffer ) => {
10+ const isHeic = ( buffer : Uint8Array ) => {
811 const brandMajor = uint8ArrayUtf8ByteString ( buffer , 8 , 12 ) . replace ( '\0' , ' ' ) . trim ( ) ;
912
1013 switch ( brandMajor ) {
@@ -23,25 +26,59 @@ const isHeic = (buffer) => {
2326 return false ;
2427} ;
2528
26- const decodeImage = async ( image ) => {
29+ const decodeImage = async (
30+ image : HeifImage
31+ ) : Promise < { width : number ; height : number ; data : Uint8ClampedArray } > => {
2732 const width = image . get_width ( ) ;
2833 const height = image . get_height ( ) ;
2934
30- const { data } = await new Promise ( ( resolve , reject ) => {
31- image . display ( { data : new Uint8ClampedArray ( width * height * 4 ) , width, height } , ( displayData ) => {
32- if ( ! displayData ) {
33- return reject ( new Error ( 'HEIF processing error' ) ) ;
34- }
35+ const { data } = await new Promise < { data : Uint8ClampedArray } > ( ( resolve , reject ) => {
36+ image . display (
37+ { data : new Uint8ClampedArray ( width * height * 4 ) , width, height } ,
38+ ( displayData ) => {
39+ if ( ! displayData ) {
40+ return reject ( new Error ( 'HEIF processing error' ) ) ;
41+ }
3542
36- resolve ( displayData ) ;
37- } ) ;
43+ resolve ( displayData ) ;
44+ }
45+ ) ;
3846 } ) ;
3947
4048 return { width, height, data } ;
4149} ;
4250
43- module . exports = libheif => {
44- const decodeBuffer = async ( { buffer, all } ) => {
51+ type DecodeOneResult = {
52+ width : number ;
53+ height : number ;
54+ data : Uint8ClampedArray ;
55+ } ;
56+
57+ type DecodeAllResult = {
58+ width : number ;
59+ height : number ;
60+ decode : ( ) => Promise < DecodeOneResult > ;
61+ } [ ] ;
62+
63+ export default function lib ( libheif : typeof libheifType ) : {
64+ one : ( options : { buffer : Uint8Array } ) => Promise < DecodeOneResult > ;
65+ all : ( options : { buffer : Uint8Array } ) => Promise < DecodeAllResult > ;
66+ } {
67+ async function decodeBuffer ( {
68+ buffer,
69+ all,
70+ } : {
71+ buffer : Uint8Array ;
72+ all : true ;
73+ } ) : Promise < DecodeAllResult > ;
74+ async function decodeBuffer ( {
75+ buffer,
76+ all,
77+ } : {
78+ buffer : Uint8Array ;
79+ all : false ;
80+ } ) : Promise < DecodeOneResult > ;
81+ async function decodeBuffer ( { buffer, all } : { buffer : Uint8Array ; all : boolean } ) {
4582 if ( ! isHeic ( buffer ) ) {
4683 throw new TypeError ( 'input buffer is not a HEIC image' ) ;
4784 }
@@ -67,28 +104,32 @@ module.exports = libheif => {
67104
68105 if ( ! all ) {
69106 try {
70- return await decodeImage ( data [ 0 ] ) ;
107+ return await decodeImage ( data [ 0 ] ! ) ;
71108 } finally {
72109 dispose ( ) ;
73110 }
74111 }
75112
76- return Object . defineProperty ( data . map ( image => {
77- return {
78- width : image . get_width ( ) ,
79- height : image . get_height ( ) ,
80- decode : async ( ) => await decodeImage ( image )
81- } ;
82- } ) , 'dispose' , {
83- enumerable : false ,
84- configurable : false ,
85- writable : false ,
86- value : dispose
87- } ) ;
88- } ;
113+ return Object . defineProperty (
114+ data . map ( ( image ) => {
115+ return {
116+ width : image . get_width ( ) ,
117+ height : image . get_height ( ) ,
118+ decode : async ( ) => await decodeImage ( image ) ,
119+ } ;
120+ } ) ,
121+ 'dispose' ,
122+ {
123+ enumerable : false ,
124+ configurable : false ,
125+ writable : false ,
126+ value : dispose ,
127+ }
128+ ) ;
129+ }
89130
90131 return {
91- one : async ( { buffer } ) => await decodeBuffer ( { buffer, all : false } ) ,
92- all : async ( { buffer } ) => await decodeBuffer ( { buffer, all : true } )
132+ one : async ( { buffer } : { buffer : Uint8Array } ) => await decodeBuffer ( { buffer, all : false } ) ,
133+ all : async ( { buffer } : { buffer : Uint8Array } ) => await decodeBuffer ( { buffer, all : true } ) ,
93134 } ;
94- } ;
135+ }
0 commit comments