Skip to content

Commit 4c3397f

Browse files
committed
core: Support bitmaps larger than 65535x65535
DefineBitsJPEG2 can define bitmaps larger than 65535x65535, FP supports it, and some games use it for e.g. defining sprites on a very large bitmap. This patch migrates bitmap width/height from u16 to u32, as that's the maximum theoretical size of a PNG image. It also overall fits better with the current codebase and requires less conversions.
1 parent bb0df01 commit 4c3397f

File tree

9 files changed

+50
-49
lines changed

9 files changed

+50
-49
lines changed

core/src/avm1/globals/movie_clip.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -583,8 +583,8 @@ fn begin_bitmap_fill<'gc>(
583583
let handle = bitmap_data.bitmap_handle(activation.gc(), activation.context.renderer);
584584
let bitmap = ruffle_render::bitmap::BitmapInfo {
585585
handle,
586-
width: bitmap_data.width() as u16,
587-
height: bitmap_data.height() as u16,
586+
width: bitmap_data.width(),
587+
height: bitmap_data.height(),
588588
};
589589
let id = movie_clip.drawing_mut().add_bitmap(bitmap);
590590

core/src/avm2/globals/flash/display/graphics.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ pub fn begin_bitmap_fill<'gc>(
8080

8181
let bitmap = ruffle_render::bitmap::BitmapInfo {
8282
handle,
83-
width: bitmap.width() as u16,
84-
height: bitmap.height() as u16,
83+
width: bitmap.width(),
84+
height: bitmap.height(),
8585
};
8686
let scale_matrix = Matrix::scale(
8787
(Twips::TWIPS_PER_PIXEL as i16).into(),
@@ -1322,8 +1322,8 @@ pub fn line_bitmap_style<'gc>(
13221322

13231323
let bitmap = ruffle_render::bitmap::BitmapInfo {
13241324
handle,
1325-
width: bitmap.width() as u16,
1326-
height: bitmap.height() as u16,
1325+
width: bitmap.width(),
1326+
height: bitmap.height(),
13271327
};
13281328
let scale_matrix = Matrix::scale(
13291329
Fixed16::from_f64(bitmap.width as f64),
@@ -1789,8 +1789,8 @@ fn handle_bitmap_fill<'gc>(
17891789

17901790
let bitmap = ruffle_render::bitmap::BitmapInfo {
17911791
handle,
1792-
width: bitmap_data.width() as u16,
1793-
height: bitmap_data.height() as u16,
1792+
width: bitmap_data.width(),
1793+
height: bitmap_data.height(),
17941794
};
17951795

17961796
let scale_matrix = Matrix::scale(

core/src/character.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ pub enum CompressedBitmap {
9090
Jpeg {
9191
data: Vec<u8>,
9292
alpha: Option<Vec<u8>>,
93-
width: u16,
94-
height: u16,
93+
width: u32,
94+
height: u32,
9595
},
9696
Lossless(DefineBitsLossless<'static>),
9797
}
@@ -104,8 +104,8 @@ impl CompressedBitmap {
104104
height: *height,
105105
},
106106
CompressedBitmap::Lossless(define_bits_lossless) => BitmapSize {
107-
width: define_bits_lossless.width,
108-
height: define_bits_lossless.height,
107+
width: define_bits_lossless.width.into(),
108+
height: define_bits_lossless.height.into(),
109109
},
110110
}
111111
}

core/src/display_object.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ pub struct BitmapCache {
9898
matrix_d: f32,
9999

100100
/// The width of the original bitmap, pre-filters
101-
source_width: u16,
101+
source_width: u32,
102102

103103
/// The height of the original bitmap, pre-filters
104-
source_height: u16,
104+
source_height: u32,
105105

106106
/// The offset used to draw the final bitmap (i.e. if a filter increases the size)
107107
draw_offset: Point<i32>,
@@ -122,7 +122,7 @@ impl BitmapCache {
122122
self.matrix_a = f32::NAN;
123123
}
124124

125-
fn is_dirty(&self, other: &Matrix, source_width: u16, source_height: u16) -> bool {
125+
fn is_dirty(&self, other: &Matrix, source_width: u32, source_height: u32) -> bool {
126126
self.matrix_a != other.a
127127
|| self.matrix_b != other.b
128128
|| self.matrix_c != other.c
@@ -138,10 +138,10 @@ impl BitmapCache {
138138
&mut self,
139139
renderer: &mut dyn RenderBackend,
140140
matrix: Matrix,
141-
source_width: u16,
142-
source_height: u16,
143-
actual_width: u16,
144-
actual_height: u16,
141+
source_width: u32,
142+
source_height: u32,
143+
actual_width: u32,
144+
actual_height: u32,
145145
draw_offset: Point<i32>,
146146
swf_version: u8,
147147
) {
@@ -158,7 +158,7 @@ impl BitmapCache {
158158
}
159159
}
160160
let acceptable_size = if swf_version > 9 {
161-
let total = actual_width as u32 * actual_height as u32;
161+
let total = actual_width * actual_height;
162162
actual_width < 8191 && actual_height < 8191 && total < 16777215
163163
} else {
164164
actual_width < 2880 && actual_height < 2880
@@ -168,7 +168,7 @@ impl BitmapCache {
168168
&& actual_height > 0
169169
&& acceptable_size
170170
{
171-
let handle = renderer.create_empty_texture(actual_width as u32, actual_height as u32);
171+
let handle = renderer.create_empty_texture(actual_width, actual_height);
172172
self.bitmap = handle.ok().map(|handle| BitmapInfo {
173173
width: actual_width,
174174
height: actual_height,
@@ -944,8 +944,8 @@ pub fn render_base<'gc>(
944944
let width = bounds.width().to_pixels().ceil().max(0.0);
945945
let height = bounds.height().to_pixels().ceil().max(0.0);
946946
if width <= u16::MAX as f64 && height <= u16::MAX as f64 {
947-
let width = width as u16;
948-
let height = height as u16;
947+
let width = width as u32;
948+
let height = height as u32;
949949
let mut filter_rect = Rectangle {
950950
x_min: Twips::ZERO,
951951
x_max: Twips::from_pixels_i32(width as i32),
@@ -971,8 +971,8 @@ pub fn render_base<'gc>(
971971
base_transform.matrix,
972972
width,
973973
height,
974-
filter_rect.width() as u16,
975-
filter_rect.height() as u16,
974+
filter_rect.width() as u32,
975+
filter_rect.height() as u32,
976976
draw_offset,
977977
swf_version,
978978
);

render/src/bitmap.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ pub trait BitmapHandleImpl: Any + Debug {}
2424
#[derive(Clone, Debug)]
2525
pub struct BitmapInfo {
2626
pub handle: BitmapHandle,
27-
pub width: u16,
28-
pub height: u16,
27+
pub width: u32,
28+
pub height: u32,
2929
}
3030

3131
#[derive(Copy, Clone, Debug)]
3232
pub struct BitmapSize {
33-
pub width: u16,
34-
pub height: u16,
33+
pub width: u32,
34+
pub height: u32,
3535
}
3636

3737
/// An object that returns a bitmap given an ID.

render/src/tessellator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ impl ShapeTessellator {
117117
DrawType::Bitmap(Bitmap {
118118
matrix: swf_bitmap_to_gl_matrix(
119119
(*matrix).into(),
120-
bitmap.width.into(),
121-
bitmap.height.into(),
120+
bitmap.width,
121+
bitmap.height,
122122
),
123123
bitmap_id: *id,
124124
is_smoothed: *is_smoothed,

render/src/utils.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ pub fn decode_define_bits_jpeg(
4747
}
4848
}
4949

50-
pub fn decode_define_bits_jpeg_dimensions(data: &[u8]) -> Result<(u16, u16), Error> {
50+
pub fn decode_define_bits_jpeg_dimensions(data: &[u8]) -> Result<(u32, u32), Error> {
5151
let format = determine_jpeg_tag_format(data);
5252
match format {
53-
JpegTagFormat::Jpeg => decode_jpeg_dimensions(data),
53+
JpegTagFormat::Jpeg => decode_jpeg_dimensions(data).map(|(w, h)| (w.into(), h.into())),
5454
JpegTagFormat::Png => decode_png_dimensions(data),
55-
JpegTagFormat::Gif => decode_gif_dimensions(data),
55+
JpegTagFormat::Gif => decode_gif_dimensions(data).map(|(w, h)| (w.into(), h.into())),
5656
JpegTagFormat::Unknown => Err(Error::UnknownType),
5757
}
5858
}
@@ -358,18 +358,15 @@ pub fn decode_define_bits_lossless(
358358
))
359359
}
360360

361-
fn decode_png_dimensions(data: &[u8]) -> Result<(u16, u16), Error> {
361+
fn decode_png_dimensions(data: &[u8]) -> Result<(u32, u32), Error> {
362362
use png::Transformations;
363363

364364
let mut decoder = png::Decoder::new(Cursor::new(data));
365365
// Normalize output to 8-bit grayscale or RGB.
366366
// Ideally we'd want to normalize to 8-bit RGB only, but seems like the `png` crate provides no such a feature.
367367
decoder.set_transformations(Transformations::normalize_to_color8());
368368
let reader = decoder.read_info()?;
369-
Ok((
370-
reader.info().width.try_into().expect("Invalid PNG width"),
371-
reader.info().height.try_into().expect("Invalid PNG height"),
372-
))
369+
Ok((reader.info().width, reader.info().height))
373370
}
374371

375372
/// Decodes the bitmap data in DefineBitsLossless tag into RGBA.

video/external/src/backend.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,15 @@ impl VideoBackend for ExternalVideoBackend {
183183
ProxyOrStream::Owned(stream) => {
184184
let frame = stream.decoder.decode_frame(encoded_frame)?;
185185

186-
let w = frame.width();
187-
let h = frame.height();
186+
let width = frame.width();
187+
let height = frame.height();
188188

189189
let handle = if let Some(bitmap) = stream.bitmap.clone() {
190-
renderer.update_texture(&bitmap, frame, PixelRegion::for_whole_size(w, h))?;
190+
renderer.update_texture(
191+
&bitmap,
192+
frame,
193+
PixelRegion::for_whole_size(width, height),
194+
)?;
191195
bitmap
192196
} else {
193197
renderer.register_bitmap(frame)?
@@ -196,8 +200,8 @@ impl VideoBackend for ExternalVideoBackend {
196200

197201
Ok(BitmapInfo {
198202
handle,
199-
width: w as u16,
200-
height: h as u16,
203+
width,
204+
height,
201205
})
202206
}
203207
}

video/software/src/backend.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ impl VideoBackend for SoftwareVideoBackend {
8888

8989
let frame = stream.decoder.decode_frame(encoded_frame)?;
9090

91-
let w = frame.width();
92-
let h = frame.height();
91+
let width = frame.width();
92+
let height = frame.height();
9393

9494
let handle = if let Some(bitmap) = stream.bitmap.clone() {
95-
renderer.update_texture(&bitmap, frame, PixelRegion::for_whole_size(w, h))?;
95+
renderer.update_texture(&bitmap, frame, PixelRegion::for_whole_size(width, height))?;
9696
bitmap
9797
} else {
9898
renderer.register_bitmap(frame)?
@@ -101,8 +101,8 @@ impl VideoBackend for SoftwareVideoBackend {
101101

102102
Ok(BitmapInfo {
103103
handle,
104-
width: w as u16,
105-
height: h as u16,
104+
width,
105+
height,
106106
})
107107
}
108108
}

0 commit comments

Comments
 (0)