@@ -97,6 +97,7 @@ fn embed_images_from_expression(
9797 if embed_files != EmbedResourcesKind :: Nothing
9898 && ( embed_files != EmbedResourcesKind :: OnlyBuiltinResources
9999 || path. starts_with ( "builtin:/" ) )
100+ && ( path. starts_with ( "data:image/" ) || !path. starts_with ( "data:" ) )
100101 {
101102 let image_ref = embed_image (
102103 global_embedded_resources,
@@ -143,6 +144,44 @@ fn embed_image(
143144 // Really do nothing with the image!
144145 e. insert ( EmbeddedResources { id : maybe_id, kind : EmbeddedResourcesKind :: ListOnly } ) ;
145146 return ImageReference :: None ;
147+ } else if path. starts_with ( "data:" ) {
148+ // Handle data URLs by decoding them at compile time
149+ if let Ok ( data_url) = dataurl:: DataUrl :: parse ( path) {
150+ let media_type = data_url. get_media_type ( ) ;
151+ if !media_type. starts_with ( "image/" ) {
152+ // Non-image data URLs are not embedded, they remain as AbsolutePath
153+ // and will be handled at runtime (e.g., for plain text)
154+ return ImageReference :: AbsolutePath ( path. into ( ) ) ;
155+ }
156+
157+ let extension = media_type. split ( '/' ) . nth ( 1 ) . unwrap_or ( "" ) . to_string ( ) ;
158+ let decoded_data = if data_url. get_is_base64_encoded ( ) {
159+ data_url. get_data ( ) . to_vec ( )
160+ } else {
161+ data_url. get_text ( ) . as_bytes ( ) . to_vec ( )
162+ } ;
163+
164+ // Check for oversized data URLs (> 1 MiB)
165+ const MAX_DATA_URL_SIZE : usize = 1024 * 1024 ; // 1 MiB
166+ if decoded_data. len ( ) > MAX_DATA_URL_SIZE {
167+ diag. push_error (
168+ format ! (
169+ "Data URL is too large ({} bytes > {} bytes). Consider using a file reference instead." ,
170+ decoded_data. len( ) ,
171+ MAX_DATA_URL_SIZE
172+ ) ,
173+ source_location,
174+ ) ;
175+ return ImageReference :: None ;
176+ }
177+
178+ // For data URLs, store the decoded data with its extension
179+ let kind = EmbeddedResourcesKind :: DecodedData ( decoded_data, extension) ;
180+ e. insert ( EmbeddedResources { id : maybe_id, kind } )
181+ } else {
182+ diag. push_error ( format ! ( "Invalid data URL format: {}" , path) , source_location) ;
183+ return ImageReference :: None ;
184+ }
146185 } else if let Some ( _file) = crate :: fileaccess:: load_file ( std:: path:: Path :: new ( path) ) {
147186 #[ allow( unused_mut) ]
148187 let mut kind = EmbeddedResourcesKind :: RawData ;
@@ -173,11 +212,14 @@ fn embed_image(
173212 }
174213 } ;
175214
176- match e. kind {
215+ match & e. kind {
177216 #[ cfg( feature = "software-renderer" ) ]
178217 EmbeddedResourcesKind :: TextureData { .. } => {
179218 ImageReference :: EmbeddedTexture { resource_id : e. id }
180219 }
220+ EmbeddedResourcesKind :: DecodedData ( _, extension) => {
221+ ImageReference :: EmbeddedData { resource_id : e. id , extension : extension. clone ( ) }
222+ }
181223 _ => ImageReference :: EmbeddedData {
182224 resource_id : e. id ,
183225 extension : std:: path:: Path :: new ( path)
0 commit comments