processImage( image, format, flipY ) {

			const writer = this;
			const cache = writer.cache;
			const json = writer.json;
			const options = writer.options;
			const pending = writer.pending;
			if ( ! cache.images.has( image ) ) cache.images.set( image, {} );
			const cachedImages = cache.images.get( image );
			const mimeType = format === THREE.RGBAFormat ? 'image/png' : 'image/jpeg';
			const key = mimeType + ':flipY/' + flipY.toString();
			if ( cachedImages[ key ] !== undefined ) return cachedImages[ key ];
			if ( ! json.images ) json.images = [];
			const imageDef = {
				mimeType: mimeType
			};

			if ( options.embedImages ) {

				const canvas = cachedCanvas = cachedCanvas || document.createElement( 'canvas' );
				canvas.width = Math.min( image.width, options.maxTextureSize );
				canvas.height = Math.min( image.height, options.maxTextureSize );
				const ctx = canvas.getContext( '2d' );

				if ( flipY === true ) {

					ctx.translate( 0, canvas.height );
					ctx.scale( 1, - 1 );

				}

				if ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) {

					ctx.drawImage( image, 0, 0, canvas.width, canvas.height );

				} else {

					if ( format !== THREE.RGBAFormat && format !== THREE.RGBFormat ) {

						console.error( 'GLTFExporter: Only RGB and RGBA formats are supported.' );

					}

					if ( image.width > options.maxTextureSize || image.height > options.maxTextureSize ) {

						console.warn( 'GLTFExporter: Image size is bigger than maxTextureSize', image );

					}

					const data = new Uint8ClampedArray( image.height * image.width * 4 );

					if ( format === THREE.RGBAFormat ) {

						for ( let i = 0; i < data.length; i += 4 ) {

							data[ i + 0 ] = image.data[ i + 0 ];
							data[ i + 1 ] = image.data[ i + 1 ];
							data[ i + 2 ] = image.data[ i + 2 ];
							data[ i + 3 ] = image.data[ i + 3 ];

						}

					} else {

						for ( let i = 0, j = 0; i < data.length; i += 4, j += 3 ) {

							data[ i + 0 ] = image.data[ j + 0 ];
							data[ i + 1 ] = image.data[ j + 1 ];
							data[ i + 2 ] = image.data[ j + 2 ];
							data[ i + 3 ] = 255;

						}

					}

					ctx.putImageData( new ImageData( data, image.width, image.height ), 0, 0 );

				}

				if ( options.binary === true ) {

					pending.push( new Promise( function ( resolve ) {

						canvas.toBlob( function ( blob ) {

							writer.processBufferViewImage( blob ).then( function ( bufferViewIndex ) {

								imageDef.bufferView = bufferViewIndex;
								resolve();

							} );

						}, mimeType );

					} ) );

				} else {

					imageDef.uri = canvas.toDataURL( mimeType );

				}

			} else {

				imageDef.uri = image.src;

			}

			const index = json.images.push( imageDef ) - 1;
			cachedImages[ key ] = index;
			return index;

		}
Process image
@param  {Image} image to process
@param  {Integer} format of the image (e.g. THREE.RGBFormat, THREE.RGBAFormat etc)
@param  {Boolean} flipY before writing out the image
@return {Integer}     Index of the processed texture in the "images" array