@@ -9,6 +9,20 @@ pub(crate) fn process_image(
99 source : & Path ,
1010 output_path : & Path ,
1111) -> anyhow:: Result < ( ) > {
12+ // Copy verbatim if no transform is requested (#5642)
13+ if image_options. format ( ) == ImageFormat :: Unknown
14+ && image_options. size ( ) == ImageSize :: Automatic
15+ {
16+ std:: fs:: copy ( source, output_path) . with_context ( || {
17+ format ! (
18+ "Failed to copy image from {} to {}" ,
19+ source. display( ) ,
20+ output_path. display( )
21+ )
22+ } ) ?;
23+ return Ok ( ( ) ) ;
24+ }
25+
1226 let mut image = image:: ImageReader :: new ( std:: io:: Cursor :: new ( & * std:: fs:: read ( source) ?) )
1327 . with_guessed_format ( )
1428 . context ( "Failed to guess image format" ) ?
@@ -141,3 +155,49 @@ pub(crate) fn compress_jpg(image: DynamicImage, output_location: &Path) -> anyho
141155 w. write_all ( & jpeg_bytes) ?;
142156 Ok ( ( ) )
143157}
158+
159+ #[ cfg( test) ]
160+ mod tests {
161+ use super :: * ;
162+
163+ // Write a PNG with detectable chunk/compression to verify byte-for-byte copying
164+ fn write_source_png ( path : & Path ) {
165+ let file = std:: fs:: File :: create ( path) . unwrap ( ) ;
166+ let w = BufWriter :: new ( file) ;
167+ let mut encoder = png:: Encoder :: new ( w, 4 , 4 ) ;
168+ encoder. set_color ( png:: ColorType :: Rgba ) ;
169+ encoder. set_depth ( png:: BitDepth :: Eight ) ;
170+ encoder. set_compression ( png:: Compression :: Best ) ;
171+ encoder
172+ . add_text_chunk ( "Comment" . to_string ( ) , "dioxus-asset-test" . to_string ( ) )
173+ . unwrap ( ) ;
174+ let mut writer = encoder. write_header ( ) . unwrap ( ) ;
175+ // 4x4 RGBA pixels with varied colors.
176+ let mut data = Vec :: with_capacity ( 4 * 4 * 4 ) ;
177+ for i in 0 ..16u8 {
178+ data. extend_from_slice ( & [ i. wrapping_mul ( 16 ) , 255 - i, i, 255 ] ) ;
179+ }
180+ writer. write_image_data ( & data) . unwrap ( ) ;
181+ writer. finish ( ) . unwrap ( ) ;
182+ }
183+
184+ // Test for #5642: `asset!()` must copy bytes verbatim
185+ #[ test]
186+ fn default_options_preserve_source_bytes ( ) {
187+ let dir = std:: env:: temp_dir ( ) . join ( format ! ( "dx-image-opt-test-{}" , std:: process:: id( ) ) ) ;
188+ std:: fs:: create_dir_all ( & dir) . unwrap ( ) ;
189+ let source = dir. join ( "source.png" ) ;
190+ let output = dir. join ( "output.png" ) ;
191+ write_source_png ( & source) ;
192+
193+ process_image ( & ImageAssetOptions :: default ( ) , & source, & output) . unwrap ( ) ;
194+
195+ assert_eq ! (
196+ std:: fs:: read( & source) . unwrap( ) ,
197+ std:: fs:: read( & output) . unwrap( ) ,
198+ "asset!() with default options must copy the source bytes verbatim, not re-encode"
199+ ) ;
200+
201+ std:: fs:: remove_dir_all ( & dir) . ok ( ) ;
202+ }
203+ }
0 commit comments