core: Move compare from BitmapData to bitmap_data_operations
This commit is contained in:
parent
8a0cb4685e
commit
2c65f23eb8
|
@ -1365,10 +1365,8 @@ pub fn compare<'gc>(
|
|||
return Ok(BITMAP_DISPOSED.into());
|
||||
}
|
||||
|
||||
let this_bitmap_data = this_bitmap_data.bitmap_data();
|
||||
let this_bitmap_data = this_bitmap_data.read();
|
||||
let other_bitmap_data = other_bitmap_data.bitmap_data();
|
||||
let other_bitmap_data = other_bitmap_data.read();
|
||||
let this_bitmap_data = this_bitmap_data.bitmap_data_wrapper();
|
||||
let other_bitmap_data = other_bitmap_data.bitmap_data_wrapper();
|
||||
|
||||
if this_bitmap_data.width() != other_bitmap_data.width() {
|
||||
return Ok(DIFFERENT_WIDTHS.into());
|
||||
|
@ -1378,7 +1376,7 @@ pub fn compare<'gc>(
|
|||
return Ok(DIFFERENT_HEIGHTS.into());
|
||||
}
|
||||
|
||||
match BitmapData::compare(&this_bitmap_data, &other_bitmap_data) {
|
||||
match bitmap_data_operations::compare(this_bitmap_data, other_bitmap_data) {
|
||||
Some(bitmap_data) => Ok(BitmapDataObject::with_bitmap_data(
|
||||
activation.context.gc_context,
|
||||
activation.context.avm1.prototypes().bitmap_data,
|
||||
|
|
|
@ -450,6 +450,24 @@ impl<'gc> BitmapData<'gc> {
|
|||
self.set_cpu_dirty(PixelRegion::for_whole_size(width, height));
|
||||
}
|
||||
|
||||
pub fn new_with_pixels(
|
||||
width: u32,
|
||||
height: u32,
|
||||
transparency: bool,
|
||||
pixels: Vec<Color>,
|
||||
) -> Self {
|
||||
Self {
|
||||
pixels,
|
||||
width,
|
||||
height,
|
||||
transparency,
|
||||
bitmap_handle: None,
|
||||
avm2_object: None,
|
||||
disposed: false,
|
||||
dirty_state: DirtyState::Clean,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_valid(
|
||||
&self,
|
||||
activation: &mut crate::avm2::Activation<'_, 'gc>,
|
||||
|
@ -839,56 +857,6 @@ impl<'gc> BitmapData<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Compare two BitmapData objects.
|
||||
/// Returns `None` if the bitmaps are equivalent.
|
||||
pub fn compare(bitmap: &Self, other: &Self) -> Option<Self> {
|
||||
// This function expects that the two bitmaps have the same dimensions.
|
||||
// TODO: Relax this assumption and return a special value instead?
|
||||
debug_assert_eq!(bitmap.width, other.width);
|
||||
debug_assert_eq!(bitmap.height, other.height);
|
||||
|
||||
let mut different = false;
|
||||
let pixels = bitmap
|
||||
.pixels
|
||||
.iter()
|
||||
.zip(&other.pixels)
|
||||
.map(|(bitmap_pixel, other_pixel)| {
|
||||
let bitmap_pixel = bitmap_pixel.to_un_multiplied_alpha();
|
||||
let other_pixel = other_pixel.to_un_multiplied_alpha();
|
||||
if bitmap_pixel == other_pixel {
|
||||
Color::argb(0, 0, 0, 0)
|
||||
} else if bitmap_pixel.with_alpha(0) != other_pixel.with_alpha(0) {
|
||||
different = true;
|
||||
Color::argb(
|
||||
0xff,
|
||||
bitmap_pixel.red().wrapping_sub(other_pixel.red()),
|
||||
bitmap_pixel.green().wrapping_sub(other_pixel.green()),
|
||||
bitmap_pixel.blue().wrapping_sub(other_pixel.blue()),
|
||||
)
|
||||
} else {
|
||||
different = true;
|
||||
let alpha = bitmap_pixel.alpha().wrapping_sub(other_pixel.alpha());
|
||||
Color::argb(alpha, alpha, alpha, alpha)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
if different {
|
||||
Some(Self {
|
||||
pixels,
|
||||
width: bitmap.width,
|
||||
height: bitmap.height,
|
||||
transparency: true,
|
||||
bitmap_handle: None,
|
||||
avm2_object: None,
|
||||
disposed: false,
|
||||
dirty_state: DirtyState::Clean,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn object2(&self) -> Avm2Value<'gc> {
|
||||
self.avm2_object
|
||||
.map(|o| o.into())
|
||||
|
|
|
@ -672,3 +672,57 @@ pub fn palette_map<'gc>(
|
|||
dirty_region.clamp(write.width(), write.height());
|
||||
write.set_cpu_dirty(dirty_region);
|
||||
}
|
||||
|
||||
/// Compare two BitmapData objects.
|
||||
/// Returns `None` if the bitmaps are equivalent.
|
||||
pub fn compare<'gc>(
|
||||
left: BitmapDataWrapper<'gc>,
|
||||
right: BitmapDataWrapper<'gc>,
|
||||
) -> Option<BitmapData<'gc>> {
|
||||
// This function expects that the two bitmaps have the same dimensions.
|
||||
// TODO: Relax this assumption and return a special value instead?
|
||||
debug_assert_eq!(left.width(), right.width());
|
||||
debug_assert_eq!(left.height(), right.height());
|
||||
|
||||
let left = left.sync();
|
||||
let left = left.read();
|
||||
let right = right.sync();
|
||||
let right = right.read();
|
||||
|
||||
let mut different = false;
|
||||
let pixels = left
|
||||
.pixels()
|
||||
.iter()
|
||||
.zip(right.pixels())
|
||||
.map(|(bitmap_pixel, other_pixel)| {
|
||||
let bitmap_pixel = bitmap_pixel.to_un_multiplied_alpha();
|
||||
let other_pixel = other_pixel.to_un_multiplied_alpha();
|
||||
if bitmap_pixel == other_pixel {
|
||||
Color::argb(0, 0, 0, 0)
|
||||
} else if bitmap_pixel.with_alpha(0) != other_pixel.with_alpha(0) {
|
||||
different = true;
|
||||
Color::argb(
|
||||
0xff,
|
||||
bitmap_pixel.red().wrapping_sub(other_pixel.red()),
|
||||
bitmap_pixel.green().wrapping_sub(other_pixel.green()),
|
||||
bitmap_pixel.blue().wrapping_sub(other_pixel.blue()),
|
||||
)
|
||||
} else {
|
||||
different = true;
|
||||
let alpha = bitmap_pixel.alpha().wrapping_sub(other_pixel.alpha());
|
||||
Color::argb(alpha, alpha, alpha, alpha)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
if different {
|
||||
Some(BitmapData::new_with_pixels(
|
||||
left.width(),
|
||||
left.height(),
|
||||
true,
|
||||
pixels,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue