render: Random cleanups
Avoid some `Vec::with_capacity` and de-duplicate code.
This commit is contained in:
parent
9d4ab37ef6
commit
c31e9e2b11
|
@ -113,15 +113,7 @@ fn decode_jpeg(jpeg_data: &[u8], alpha_data: Option<&[u8]>) -> Result<Bitmap, Er
|
||||||
[r as u8, g as u8, b as u8]
|
[r as u8, g as u8, b as u8]
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
jpeg_decoder::PixelFormat::L8 => {
|
jpeg_decoder::PixelFormat::L8 => decoded_data.iter().flat_map(|&c| [c, c, c]).collect(),
|
||||||
let mut rgb = Vec::with_capacity(decoded_data.len() * 3);
|
|
||||||
for elem in decoded_data {
|
|
||||||
rgb.push(elem);
|
|
||||||
rgb.push(elem);
|
|
||||||
rgb.push(elem);
|
|
||||||
}
|
|
||||||
rgb
|
|
||||||
}
|
|
||||||
jpeg_decoder::PixelFormat::L16 => {
|
jpeg_decoder::PixelFormat::L16 => {
|
||||||
log::warn!("Unimplemented L16 JPEG pixel format");
|
log::warn!("Unimplemented L16 JPEG pixel format");
|
||||||
decoded_data
|
decoded_data
|
||||||
|
@ -133,22 +125,21 @@ fn decode_jpeg(jpeg_data: &[u8], alpha_data: Option<&[u8]>) -> Result<Bitmap, Er
|
||||||
let alpha_data = decompress_zlib(alpha_data)?;
|
let alpha_data = decompress_zlib(alpha_data)?;
|
||||||
|
|
||||||
if alpha_data.len() == decoded_data.len() / 3 {
|
if alpha_data.len() == decoded_data.len() / 3 {
|
||||||
let mut rgba = Vec::with_capacity((decoded_data.len() / 3) * 4);
|
let rgba = decoded_data
|
||||||
let mut i = 0;
|
.chunks_exact(3)
|
||||||
let mut a = 0;
|
.zip(alpha_data)
|
||||||
while i < decoded_data.len() {
|
.flat_map(|(rgb, a)| {
|
||||||
// The JPEG data should be premultiplied alpha, but it isn't in some incorrect SWFs (see #6893).
|
// The JPEG data should be premultiplied alpha, but it isn't in some incorrect
|
||||||
// This means 0% alpha pixels may have color and incorrectly show as visible.
|
// SWFs (see #6893).
|
||||||
// Flash Player clamps color to the alpha value to fix this case.
|
// This means 0% alpha pixels may have color and incorrectly show as visible.
|
||||||
// Only applies to DefineBitsJPEG3; DefineBitsLossless does not seem to clamp.
|
// Flash Player clamps color to the alpha value to fix this case.
|
||||||
let alpha = alpha_data[a];
|
// Only applies to DefineBitsJPEG3; DefineBitsLossless does not seem to clamp.
|
||||||
rgba.push(decoded_data[i].min(alpha));
|
let r = rgb[0].min(a);
|
||||||
rgba.push(decoded_data[i + 1].min(alpha));
|
let g = rgb[1].min(a);
|
||||||
rgba.push(decoded_data[i + 2].min(alpha));
|
let b = rgb[2].min(a);
|
||||||
rgba.push(alpha);
|
[r, g, b, a]
|
||||||
i += 3;
|
})
|
||||||
a += 1;
|
.collect();
|
||||||
}
|
|
||||||
return Ok(Bitmap::new(
|
return Ok(Bitmap::new(
|
||||||
metadata.width.into(),
|
metadata.width.into(),
|
||||||
metadata.height.into(),
|
metadata.height.into(),
|
||||||
|
@ -188,39 +179,28 @@ pub fn decode_define_bits_lossless(swf_tag: &swf::DefineBitsLossless) -> Result<
|
||||||
for _ in 0..swf_tag.width {
|
for _ in 0..swf_tag.width {
|
||||||
let compressed = u16::from_be_bytes([decoded_data[i], decoded_data[i + 1]]);
|
let compressed = u16::from_be_bytes([decoded_data[i], decoded_data[i + 1]]);
|
||||||
let rgb5_component = |shift: u16| {
|
let rgb5_component = |shift: u16| {
|
||||||
let component = compressed >> shift & 0x1F;
|
let component = (compressed >> shift) & 0x1F;
|
||||||
((component * 255 + 15) / 31) as u8
|
((component * 255 + 15) / 31) as u8
|
||||||
};
|
};
|
||||||
out_data.push(rgb5_component(10));
|
out_data.extend([
|
||||||
out_data.push(rgb5_component(5));
|
rgb5_component(10),
|
||||||
out_data.push(rgb5_component(0));
|
rgb5_component(5),
|
||||||
out_data.push(0xff);
|
rgb5_component(0),
|
||||||
|
0xff,
|
||||||
|
]);
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
i += (padded_width - swf_tag.width) as usize * 2;
|
i += (padded_width - swf_tag.width) as usize * 2;
|
||||||
}
|
}
|
||||||
out_data
|
out_data
|
||||||
}
|
}
|
||||||
(1, swf::BitmapFormat::Rgb32) => {
|
(1 | 2, swf::BitmapFormat::Rgb32) => {
|
||||||
let mut i = 0;
|
let has_alpha = swf_tag.version == 2;
|
||||||
while i < decoded_data.len() {
|
for rgba in decoded_data.chunks_exact_mut(4) {
|
||||||
decoded_data[i] = decoded_data[i + 1];
|
rgba.rotate_left(1);
|
||||||
decoded_data[i + 1] = decoded_data[i + 2];
|
if !has_alpha {
|
||||||
decoded_data[i + 2] = decoded_data[i + 3];
|
rgba[3] = 0xff;
|
||||||
decoded_data[i + 3] = 0xff;
|
}
|
||||||
i += 4;
|
|
||||||
}
|
|
||||||
decoded_data
|
|
||||||
}
|
|
||||||
(2, swf::BitmapFormat::Rgb32) => {
|
|
||||||
let mut i = 0;
|
|
||||||
while i < decoded_data.len() {
|
|
||||||
let alpha = decoded_data[i];
|
|
||||||
decoded_data[i] = decoded_data[i + 1];
|
|
||||||
decoded_data[i + 1] = decoded_data[i + 2];
|
|
||||||
decoded_data[i + 2] = decoded_data[i + 3];
|
|
||||||
decoded_data[i + 3] = alpha;
|
|
||||||
i += 4;
|
|
||||||
}
|
}
|
||||||
decoded_data
|
decoded_data
|
||||||
}
|
}
|
||||||
|
@ -243,18 +223,8 @@ pub fn decode_define_bits_lossless(swf_tag: &swf::DefineBitsLossless) -> Result<
|
||||||
for _ in 0..swf_tag.height {
|
for _ in 0..swf_tag.height {
|
||||||
for _ in 0..swf_tag.width {
|
for _ in 0..swf_tag.width {
|
||||||
let entry = decoded_data[i] as usize;
|
let entry = decoded_data[i] as usize;
|
||||||
if entry < palette.len() {
|
let color = palette.get(entry).unwrap_or(&Color::BLACK);
|
||||||
let color = &palette[entry];
|
out_data.extend([color.r, color.g, color.b, color.a]);
|
||||||
out_data.push(color.r);
|
|
||||||
out_data.push(color.g);
|
|
||||||
out_data.push(color.b);
|
|
||||||
out_data.push(color.a);
|
|
||||||
} else {
|
|
||||||
out_data.push(0);
|
|
||||||
out_data.push(0);
|
|
||||||
out_data.push(0);
|
|
||||||
out_data.push(255);
|
|
||||||
}
|
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
i += (padded_width - swf_tag.width) as usize;
|
i += (padded_width - swf_tag.width) as usize;
|
||||||
|
@ -280,18 +250,9 @@ pub fn decode_define_bits_lossless(swf_tag: &swf::DefineBitsLossless) -> Result<
|
||||||
for _ in 0..swf_tag.height {
|
for _ in 0..swf_tag.height {
|
||||||
for _ in 0..swf_tag.width {
|
for _ in 0..swf_tag.width {
|
||||||
let entry = decoded_data[i] as usize;
|
let entry = decoded_data[i] as usize;
|
||||||
if entry < palette.len() {
|
const TRANSPARENT: Color = Color::from_rgb(0, 0);
|
||||||
let color = &palette[entry];
|
let color = palette.get(entry).unwrap_or(&TRANSPARENT);
|
||||||
out_data.push(color.r);
|
out_data.extend([color.r, color.g, color.b, color.a]);
|
||||||
out_data.push(color.g);
|
|
||||||
out_data.push(color.b);
|
|
||||||
out_data.push(color.a);
|
|
||||||
} else {
|
|
||||||
out_data.push(0);
|
|
||||||
out_data.push(0);
|
|
||||||
out_data.push(0);
|
|
||||||
out_data.push(0);
|
|
||||||
}
|
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
i += (padded_width - swf_tag.width) as usize;
|
i += (padded_width - swf_tag.width) as usize;
|
||||||
|
|
Loading…
Reference in New Issue