/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
ext/image/01_image.js
343 строки
9 KB
crowlbot
refactor(ext/web): port ImageData to Rust with CPPGC/objectwrap (#33777)
01 июн 2026, 15:51
Не верифицирован
01 июн 2026, 15:51
3b2cbfe
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. MIT license. import { core, internals, primordials } from "ext:core/mod.js"; import { ImageBitmap, op_create_image_bitmap } from "ext:core/ops"; const webidl = core.loadExtScript("ext:deno_webidl/00_webidl.js"); const { DOMException } = core.loadExtScript("ext:deno_web/01_dom_exception.js"); const { createFilteredInspectProxy } = core.loadExtScript( "ext:deno_web/01_console.js", ); const { BlobPrototype } = core.loadExtScript("ext:deno_web/09_file.js"); const { sniffImage } = core.loadExtScript("ext:deno_web/01_mimesniff.js"); const { ObjectDefineProperty, ObjectPrototypeIsPrototypeOf, SymbolFor, TypedArrayPrototypeGetBuffer, TypedArrayPrototypeGetByteOffset, TypedArrayPrototypeGetLength, TypedArrayPrototypeGetSymbolToStringTag, Uint8Array, Uint8ClampedArray, PromiseReject, RangeError, ArrayPrototypeJoin, } = primordials; let _imageDataMod; const loadImageData = () => _imageDataMod ?? (_imageDataMod = core.loadExtScript("ext:deno_web/16_image_data.js")); webidl.converters["ImageOrientation"] = webidl.createEnumConverter( "ImageOrientation", [ "from-image", "flipY", ], ); webidl.converters["PremultiplyAlpha"] = webidl.createEnumConverter( "PremultiplyAlpha", [ "none", "premultiply", "default", ], ); webidl.converters["ColorSpaceConversion"] = webidl.createEnumConverter( "ColorSpaceConversion", [ "none", "default", ], ); webidl.converters["ResizeQuality"] = webidl.createEnumConverter( "ResizeQuality", [ "pixelated", "low", "medium", "high", ], ); webidl.converters["ImageBitmapOptions"] = webidl.createDictionaryConverter( "ImageBitmapOptions", [ { key: "imageOrientation", converter: webidl.converters["ImageOrientation"], defaultValue: "from-image", }, { key: "premultiplyAlpha", converter: webidl.converters["PremultiplyAlpha"], defaultValue: "default", }, { key: "colorSpaceConversion", converter: webidl.converters["ColorSpaceConversion"], defaultValue: "default", }, { key: "resizeWidth", converter: (v, prefix, context, opts) => webidl.converters["unsigned long"](v, prefix, context, { ...opts, enforceRange: true, }), }, { key: "resizeHeight", converter: (v, prefix, context, opts) => webidl.converters["unsigned long"](v, prefix, context, { ...opts, enforceRange: true, }), }, { key: "resizeQuality", converter: webidl.converters["ResizeQuality"], defaultValue: "low", }, ], ); const ImageBitmapPrototype = ImageBitmap.prototype; const privateCustomInspect = SymbolFor("Deno.privateCustomInspect"); ObjectDefineProperty(ImageBitmapPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ object: this, evaluate: ObjectPrototypeIsPrototypeOf(ImageBitmapPrototype, this), keys: [ "width", "height", ], }), inspectOptions, ); }, }); function float16ToUnorm8(data) { const length = TypedArrayPrototypeGetLength(data); const result = new Uint8ClampedArray(length); for (let i = 0; i < length; i++) { result[i] = data[i] * 255; } return result; } function createImageBitmap( image, sxOrOptions = undefined, sy = undefined, sw = undefined, sh = undefined, options = undefined, ) { const prefix = "Failed to execute 'createImageBitmap'"; // Add the value when implementing to add support for ImageBitmapSource const imageBitmapSources = [ "Blob", "ImageData", "ImageBitmap", ]; // Overload: createImageBitmap(image [, options ]) if (arguments.length < 3) { options = webidl.converters["ImageBitmapOptions"]( sxOrOptions, prefix, "Argument 2", ); } else { // Overload: createImageBitmap(image, sx, sy, sw, sh [, options ]) sxOrOptions = webidl.converters["long"](sxOrOptions, prefix, "Argument 2"); sy = webidl.converters["long"](sy, prefix, "Argument 3"); sw = webidl.converters["long"](sw, prefix, "Argument 4"); sh = webidl.converters["long"](sh, prefix, "Argument 5"); options = webidl.converters["ImageBitmapOptions"]( options, prefix, "Argument 6", ); // 1. if (sw === 0) { return PromiseReject(new RangeError("sw has to be greater than 0")); } if (sh === 0) { return PromiseReject(new RangeError("sh has to be greater than 0")); } } // 2. if (options.resizeWidth === 0) { return PromiseReject( new DOMException( "options.resizeWidth has to be greater than 0", "InvalidStateError", ), ); } if (options.resizeHeight === 0) { return PromiseReject( new DOMException( "options.resizeHeight has to be greater than 0", "InvalidStateError", ), ); } // 3. const isBlob = ObjectPrototypeIsPrototypeOf(BlobPrototype, image); const { ImageDataPrototype } = loadImageData(); const isImageData = ObjectPrototypeIsPrototypeOf(ImageDataPrototype, image); const isImageBitmap = ObjectPrototypeIsPrototypeOf( ImageBitmapPrototype, image, ); if (!isBlob && !isImageData && !isImageBitmap) { return PromiseReject( new DOMException( `${prefix}: The provided value for 'image' is not of type '(${ ArrayPrototypeJoin(imageBitmapSources, " or ") })'`, "InvalidStateError", ), ); } // 4. return (async () => { // // For performance reasons, the arguments passed to op are represented as numbers that don't need to be serialized. // let width = 0; let height = 0; // If the image doesn't have a MIME type, mark it as 0. let mimeType = 0; let imageBitmapSource, buf; if (isBlob) { imageBitmapSource = 0; buf = new Uint8Array(await image.arrayBuffer()); // NOTE: The MIME type of image/svg+xml can't support // https://github.com/whatwg/html/pull/10172 const mimeTypeString = sniffImage(null, buf); if (mimeTypeString === "image/png") { mimeType = 1; } else if (mimeTypeString === "image/jpeg") { mimeType = 2; } else if (mimeTypeString === "image/gif") { mimeType = 3; } else if (mimeTypeString === "image/bmp") { mimeType = 4; } else if (mimeTypeString === "image/x-icon") { mimeType = 5; } else if (mimeTypeString === "image/webp") { mimeType = 6; } else { return PromiseReject( new DOMException( `The the MIME type ${mimeTypeString} of source image is not a supported format\n info: The following MIME types are supported. docs: https://mimesniff.spec.whatwg.org/#image-type-pattern-matching-algorithm\n`, "InvalidStateError", ), ); } } else if (isImageData) { width = image.width; height = image.height; imageBitmapSource = 1; let data = image.data; switch (TypedArrayPrototypeGetSymbolToStringTag(data)) { case "Float16Array": data = float16ToUnorm8(data); break; } buf = new Uint8Array( TypedArrayPrototypeGetBuffer(data), TypedArrayPrototypeGetByteOffset(data), TypedArrayPrototypeGetLength(data), ); } else if (isImageBitmap) { width = image.width; height = image.height; imageBitmapSource = 2; buf = new Uint8Array(TypedArrayPrototypeGetBuffer(image[_bitmapData]())); } // If those options are not provided, assign 0 to mean undefined(None). const _sx = typeof sxOrOptions === "number" ? sxOrOptions : 0; const _sy = sy ?? 0; const _sw = sw ?? 0; const _sh = sh ?? 0; // If those options are not provided, assign 0 to mean undefined(None). const resizeWidth = options.resizeWidth ?? 0; const resizeHeight = options.resizeHeight ?? 0; // If the imageOrientation option is set "from-image" or not set, assign 0. const imageOrientation = options.imageOrientation === "flipY" ? 1 : 0; // If the premultiplyAlpha option is "default" or not set, assign 0. let premultiplyAlpha = 0; if (options.premultiplyAlpha === "premultiply") { premultiplyAlpha = 1; } else if (options.premultiplyAlpha === "none") { premultiplyAlpha = 2; } // If the colorSpaceConversion option is "default" or not set, assign 0. const colorSpaceConversion = options.colorSpaceConversion === "none" ? 1 : 0; // If the resizeQuality option is "low" or not set, assign 0. let resizeQuality = 0; if (options.resizeQuality === "pixelated") { resizeQuality = 1; } else if (options.resizeQuality === "medium") { resizeQuality = 2; } else if (options.resizeQuality === "high") { resizeQuality = 3; } return op_create_image_bitmap( buf, width, height, _sx, _sy, _sw, _sh, imageOrientation, premultiplyAlpha, colorSpaceConversion, resizeWidth, resizeHeight, resizeQuality, imageBitmapSource, mimeType, ); })(); } const _bitmapData = SymbolFor("Deno_bitmapData"); function getBitmapData(imageBitmap) { return imageBitmap[_bitmapData](); } internals.getBitmapData = getBitmapData; export { createImageBitmap, ImageBitmap };