Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions file-formats/graphics/wow-blp/src/convert/raw1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ pub fn raw1_to_image(
pixel.0[0] = (color & 0xFF) as u8;
pixel.0[1] = ((color >> 8) & 0xFF) as u8;
pixel.0[2] = ((color >> 16) & 0xFF) as u8;
pixel.0[3] = (raw_image.indexed_alpha[i / 8] >> (i % 8)) & 0x01;
let bit = (raw_image.indexed_alpha[i / 8] >> (i % 8)) & 0x01;
pixel.0[3] = if bit == 1 { 255 } else { 0 };
}
Ok(DynamicImage::ImageRgba8(res_image))
} else if alpha_bits == 4 {
Expand All @@ -79,11 +80,12 @@ pub fn raw1_to_image(
pixel.0[1] = ((color >> 8) & 0xFF) as u8;
pixel.0[2] = ((color >> 16) & 0xFF) as u8;
let alpha_block = raw_image.indexed_alpha[i / 2];
pixel.0[3] = if i % 2 == 0 {
alpha_block
let nibble = if i % 2 == 0 {
alpha_block & 0x0F
} else {
alpha_block >> 4
};
pixel.0[3] = (nibble << 4) | nibble;
}
Ok(DynamicImage::ImageRgba8(res_image))
} else if alpha_bits == 8 {
Expand Down
98 changes: 98 additions & 0 deletions file-formats/graphics/wow-blp/tests/integration/format_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,101 @@ fn test_round_trip_blp1_raw1() {
assert_eq!(result_image.width(), 64);
assert_eq!(result_image.height(), 64);
}

#[test]
fn test_raw1_1bit_alpha_scaling() {
use image::DynamicImage;

// Create a test image with checkerboard alpha pattern
let mut img = image::RgbaImage::new(64, 64);
for (x, y, pixel) in img.enumerate_pixels_mut() {
let alpha = if (x + y) % 2 == 0 { 255 } else { 0 };
*pixel = image::Rgba([128, 128, 128, alpha]);
}
let test_image = DynamicImage::ImageRgba8(img);

// Convert to BLP with 1-bit alpha
let make_mipmaps = false;
let target = BlpTarget::Blp1(BlpOldFormat::Raw1 {
alpha_bits: AlphaBits::Bit1,
});

let blp = image_to_blp(
test_image.clone(),
make_mipmaps,
target,
FilterType::Nearest,
)
.expect("Failed to convert image to BLP");

// Save to memory buffer
let buffer = wow_blp::encode::encode_blp(&blp).expect("Failed to encode BLP");

// Load back from buffer
let loaded_blp = wow_blp::parser::parse_blp(&buffer).expect("Failed to parse BLP");

// Convert back to image
let result_image = blp_to_image(&loaded_blp, 0).expect("Failed to convert BLP to image");
let result_rgba = result_image.to_rgba8();

// Verify alpha is scaled to 0 or 255
for (x, y, pixel) in result_rgba.enumerate_pixels() {
let expected_alpha = if (x + y) % 2 == 0 { 255 } else { 0 };
assert_eq!(
pixel[3], expected_alpha,
"Alpha at ({}, {}) should be {} but was {}",
x, y, expected_alpha, pixel[3]
);
}
}

#[test]
fn test_raw1_4bit_alpha_scaling() {
use image::DynamicImage;

// Create a test image with various alpha values
let mut img = image::RgbaImage::new(64, 64);
for (x, y, pixel) in img.enumerate_pixels_mut() {
// Create a gradient of alpha values
let alpha = ((x as u16 * 255) / 63) as u8;
*pixel = image::Rgba([128, 128, 128, alpha]);
}
let test_image = DynamicImage::ImageRgba8(img);

// Convert to BLP with 4-bit alpha
let make_mipmaps = false;
let target = BlpTarget::Blp1(BlpOldFormat::Raw1 {
alpha_bits: AlphaBits::Bit4,
});

let blp = image_to_blp(
test_image.clone(),
make_mipmaps,
target,
FilterType::Nearest,
)
.expect("Failed to convert image to BLP");

// Save to memory buffer
let buffer = wow_blp::encode::encode_blp(&blp).expect("Failed to encode BLP");

// Load back from buffer
let loaded_blp = wow_blp::parser::parse_blp(&buffer).expect("Failed to parse BLP");

// Convert back to image
let result_image = blp_to_image(&loaded_blp, 0).expect("Failed to convert BLP to image");
let result_rgba = result_image.to_rgba8();

// Verify alpha is scaled properly (4-bit -> 8-bit via multiplying by 17)
for (x, _, pixel) in result_rgba.enumerate_pixels() {
// The original alpha was quantized to 4 bits, then scaled back up
// We should get values like 0, 17, 34, 51, 68, ... 255
// Check that alpha is a valid scaled 4-bit value
let alpha = pixel[3];
assert!(
alpha % 17 == 0,
"Alpha {} at x={} is not a valid scaled 4-bit value",
alpha, x
);
}
}