Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
boytacean
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
João Magalhães
boytacean
Commits
15828c2d
Verified
Commit
15828c2d
authored
9 months ago
by
João Magalhães
Browse files
Options
Downloads
Patches
Plain Diff
chore: remove unsafe tag from copy fast
parent
ad6f3971
No related branches found
No related tags found
No related merge requests found
Pipeline
#4401
passed
9 months ago
Stage: build
Stage: test
Stage: deploy
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/color.rs
+348
-351
348 additions, 351 deletions
src/color.rs
src/util.rs
+6
-4
6 additions, 4 deletions
src/util.rs
with
354 additions
and
355 deletions
src/color.rs
+
348
−
351
View file @
15828c2d
//! Color manipulation functions and constants.
//! Color manipulation functions and constants.
use
crate
::
util
::
copy_fast
;
use
crate
::
util
::
copy_fast
;
pub
const
RGB_SIZE
:
usize
=
3
;
pub
const
RGB_SIZE
:
usize
=
3
;
pub
const
RGBA_SIZE
:
usize
=
4
;
pub
const
RGBA_SIZE
:
usize
=
4
;
pub
const
RGB888_SIZE
:
usize
=
3
;
pub
const
RGB888_SIZE
:
usize
=
3
;
pub
const
XRGB8888_SIZE
:
usize
=
4
;
pub
const
XRGB8888_SIZE
:
usize
=
4
;
pub
const
RGB1555_SIZE
:
usize
=
2
;
pub
const
RGB1555_SIZE
:
usize
=
2
;
pub
const
RGB565_SIZE
:
usize
=
2
;
pub
const
RGB565_SIZE
:
usize
=
2
;
/// Defines the Game Boy pixel type as a buffer
/// Defines the Game Boy pixel type as a buffer
/// with the size of RGB (3 bytes).
/// with the size of RGB (3 bytes).
pub
type
Pixel
=
[
u8
;
RGB_SIZE
];
pub
type
Pixel
=
[
u8
;
RGB_SIZE
];
/// Defines a transparent Game Boy pixel type as a buffer
/// Defines a transparent Game Boy pixel type as a buffer
/// with the size of RGBA (4 bytes).
/// with the size of RGBA (4 bytes).
pub
type
PixelAlpha
=
[
u8
;
RGBA_SIZE
];
pub
type
PixelAlpha
=
[
u8
;
RGBA_SIZE
];
/// Defines a pixel with 5 bits per channel plus a padding
/// Defines a pixel with 5 bits per channel plus a padding
/// bit at the beginning.
/// bit at the beginning.
pub
type
PixelRgb1555
=
[
u8
;
RGB1555_SIZE
];
pub
type
PixelRgb1555
=
[
u8
;
RGB1555_SIZE
];
/// Defines a pixel with 5 bits per channel except for the
/// Defines a pixel with 5 bits per channel except for the
/// green channel which uses 6 bits.
/// green channel which uses 6 bits.
pub
type
PixelRgb565
=
[
u8
;
RGB565_SIZE
];
pub
type
PixelRgb565
=
[
u8
;
RGB565_SIZE
];
pub
fn
rgb555_to_rgb888
(
first
:
u8
,
second
:
u8
)
->
Pixel
{
pub
fn
rgb555_to_rgb888
(
first
:
u8
,
second
:
u8
)
->
Pixel
{
let
r
=
(
first
&
0x1f
)
<<
3
;
let
r
=
(
first
&
0x1f
)
<<
3
;
let
g
=
(((
first
&
0xe0
)
>>
5
)
|
((
second
&
0x03
)
<<
3
))
<<
3
;
let
g
=
(((
first
&
0xe0
)
>>
5
)
|
((
second
&
0x03
)
<<
3
))
<<
3
;
let
b
=
((
second
&
0x7c
)
>>
2
)
<<
3
;
let
b
=
((
second
&
0x7c
)
>>
2
)
<<
3
;
[
r
,
g
,
b
]
[
r
,
g
,
b
]
}
}
pub
fn
rgb888_to_rgb1555
(
first
:
u8
,
second
:
u8
,
third
:
u8
)
->
PixelRgb1555
{
pub
fn
rgb888_to_rgb1555
(
first
:
u8
,
second
:
u8
,
third
:
u8
)
->
PixelRgb1555
{
let
pixel
=
rgb888_to_rgb1555_u16
(
first
,
second
,
third
);
let
pixel
=
rgb888_to_rgb1555_u16
(
first
,
second
,
third
);
[
pixel
as
u8
,
(
pixel
>>
8
)
as
u8
]
[
pixel
as
u8
,
(
pixel
>>
8
)
as
u8
]
}
}
pub
fn
rgb888_to_rgb1555_u16
(
first
:
u8
,
second
:
u8
,
third
:
u8
)
->
u16
{
pub
fn
rgb888_to_rgb1555_u16
(
first
:
u8
,
second
:
u8
,
third
:
u8
)
->
u16
{
let
r
=
(
first
as
u16
>>
3
)
&
0x1f
;
let
r
=
(
first
as
u16
>>
3
)
&
0x1f
;
let
g
=
(
second
as
u16
>>
3
)
&
0x1f
;
let
g
=
(
second
as
u16
>>
3
)
&
0x1f
;
let
b
=
(
third
as
u16
>>
3
)
&
0x1f
;
let
b
=
(
third
as
u16
>>
3
)
&
0x1f
;
let
a
=
1
;
let
a
=
1
;
(
a
<<
15
)
|
(
r
<<
10
)
|
(
g
<<
5
)
|
b
(
a
<<
15
)
|
(
r
<<
10
)
|
(
g
<<
5
)
|
b
}
}
pub
fn
rgb888_to_rgb565
(
first
:
u8
,
second
:
u8
,
third
:
u8
)
->
PixelRgb565
{
pub
fn
rgb888_to_rgb565
(
first
:
u8
,
second
:
u8
,
third
:
u8
)
->
PixelRgb565
{
let
pixel
=
rgb888_to_rgb565_u16
(
first
,
second
,
third
);
let
pixel
=
rgb888_to_rgb565_u16
(
first
,
second
,
third
);
[
pixel
as
u8
,
(
pixel
>>
8
)
as
u8
]
[
pixel
as
u8
,
(
pixel
>>
8
)
as
u8
]
}
}
pub
fn
rgb888_to_rgb565_u16
(
first
:
u8
,
second
:
u8
,
third
:
u8
)
->
u16
{
pub
fn
rgb888_to_rgb565_u16
(
first
:
u8
,
second
:
u8
,
third
:
u8
)
->
u16
{
let
r
=
(
first
as
u16
>>
3
)
&
0x1f
;
let
r
=
(
first
as
u16
>>
3
)
&
0x1f
;
let
g
=
(
second
as
u16
>>
2
)
&
0x3f
;
let
g
=
(
second
as
u16
>>
2
)
&
0x3f
;
let
b
=
(
third
as
u16
>>
3
)
&
0x1f
;
let
b
=
(
third
as
u16
>>
3
)
&
0x1f
;
(
r
<<
11
)
|
(
g
<<
5
)
|
b
(
r
<<
11
)
|
(
g
<<
5
)
|
b
}
}
pub
fn
rgb888_to_rgb1555_array
(
rgb888_pixels
:
&
[
u8
],
rgb1555_pixels
:
&
mut
[
u8
])
{
pub
fn
rgb888_to_rgb1555_array
(
rgb888_pixels
:
&
[
u8
],
rgb1555_pixels
:
&
mut
[
u8
])
{
#[cfg(feature
=
"simd"
)]
#[cfg(feature
=
"simd"
)]
{
{
rgb888_to_rgb1555_simd
(
rgb888_pixels
,
rgb1555_pixels
);
rgb888_to_rgb1555_simd
(
rgb888_pixels
,
rgb1555_pixels
);
}
}
#[cfg(not(feature
=
"simd"
))]
#[cfg(not(feature
=
"simd"
))]
{
{
rgb888_to_rgb1555_scalar
(
rgb888_pixels
,
rgb1555_pixels
);
rgb888_to_rgb1555_scalar
(
rgb888_pixels
,
rgb1555_pixels
);
}
}
}
}
/// Converts an array of RGB888 pixels to RGB565 format using a scalar implementation.
/// Converts an array of RGB888 pixels to RGB565 format using a scalar implementation.
///
///
/// This method should provide the same results as the SIMD implementation.
/// This method should provide the same results as the SIMD implementation.
pub
fn
rgb888_to_rgb1555_scalar
(
rgb888_pixels
:
&
[
u8
],
rgb1555_pixels
:
&
mut
[
u8
])
{
pub
fn
rgb888_to_rgb1555_scalar
(
rgb888_pixels
:
&
[
u8
],
rgb1555_pixels
:
&
mut
[
u8
])
{
assert!
(
assert!
(
rgb888_pixels
.len
()
%
3
==
0
,
rgb888_pixels
.len
()
%
3
==
0
,
"Length of rgb888_pixels must be a multiple of 3"
"Length of rgb888_pixels must be a multiple of 3"
);
);
assert!
(
assert!
(
rgb1555_pixels
.len
()
%
2
==
0
,
rgb1555_pixels
.len
()
%
2
==
0
,
"Length of rgb1555_pixels must be a multiple of 2"
"Length of rgb1555_pixels must be a multiple of 2"
);
);
assert!
(
assert!
(
rgb888_pixels
.len
()
/
3
==
rgb1555_pixels
.len
()
/
2
,
rgb888_pixels
.len
()
/
3
==
rgb1555_pixels
.len
()
/
2
,
"Length of rgb1555_pixels must be two thirds the length of rgb888_pixels"
"Length of rgb1555_pixels must be two thirds the length of rgb888_pixels"
);
);
for
index
in
0
..
rgb888_pixels
.len
()
/
RGB_SIZE
{
for
index
in
0
..
rgb888_pixels
.len
()
/
RGB_SIZE
{
let
(
r
,
g
,
b
)
=
(
let
(
r
,
g
,
b
)
=
(
rgb888_pixels
[
index
*
RGB_SIZE
],
rgb888_pixels
[
index
*
RGB_SIZE
],
rgb888_pixels
[
index
*
RGB_SIZE
+
1
],
rgb888_pixels
[
index
*
RGB_SIZE
+
1
],
rgb888_pixels
[
index
*
RGB_SIZE
+
2
],
rgb888_pixels
[
index
*
RGB_SIZE
+
2
],
);
);
let
rgb1555
=
rgb888_to_rgb1555
(
r
,
g
,
b
);
let
rgb1555
=
rgb888_to_rgb1555
(
r
,
g
,
b
);
unsafe
{
let
output_offset
=
index
*
RGB1555_SIZE
;
copy_fast
(
copy_fast
(
&
rgb1555
,
&
rgb1555
,
&
mut
rgb1555_pixels
[
index
*
RGB1555_SIZE
..
index
*
RGB1555_SIZE
+
RGB1555_SIZE
],
&
mut
rgb1555_pixels
[
output_offset
..
output_offset
+
RGB1555_SIZE
],
RGB1555_SIZE
,
RGB1555_SIZE
,
)
)
}
}
}
}
}
/// Converts an array of RGB888 pixels to RGB1555 format using SIMD.
/// Converts an array of RGB888 pixels to RGB1555 format using SIMD.
///
///
/// This method is only available when the `simd` feature is enabled.
/// This method is only available when the `simd` feature is enabled.
///
///
/// Note: The length of `rgb888_pixels` must be a multiple of 3, and
/// Note: The length of `rgb888_pixels` must be a multiple of 3, and
/// `rgb1555_pixels` must be a multiple of 2.
/// `rgb1555_pixels` must be a multiple of 2.
#[cfg(feature
=
"simd"
)]
#[cfg(feature
=
"simd"
)]
pub
fn
rgb888_to_rgb1555_simd
(
rgb888_pixels
:
&
[
u8
],
rgb1555_pixels
:
&
mut
[
u8
])
{
pub
fn
rgb888_to_rgb1555_simd
(
rgb888_pixels
:
&
[
u8
],
rgb1555_pixels
:
&
mut
[
u8
])
{
use
std
::
simd
::
u8x16
;
use
std
::
simd
::
u8x16
;
use
crate
::
util
::
interleave_arrays
;
use
crate
::
util
::
interleave_arrays
;
const
SIMD_WIDTH
:
usize
=
16
;
const
SIMD_WIDTH
:
usize
=
16
;
assert!
(
assert!
(
rgb888_pixels
.len
()
%
3
==
0
,
rgb888_pixels
.len
()
%
3
==
0
,
"Length of rgb888_pixels must be a multiple of 3"
"Length of rgb888_pixels must be a multiple of 3"
);
);
assert!
(
assert!
(
rgb1555_pixels
.len
()
%
2
==
0
,
rgb1555_pixels
.len
()
%
2
==
0
,
"Length of rgb1555_pixels must be a multiple of 2"
"Length of rgb1555_pixels must be a multiple of 2"
);
);
assert!
(
assert!
(
rgb888_pixels
.len
()
/
3
==
rgb1555_pixels
.len
()
/
2
,
rgb888_pixels
.len
()
/
3
==
rgb1555_pixels
.len
()
/
2
,
"Length of rgb1555_pixels must be two thirds the length of rgb888_pixels"
"Length of rgb1555_pixels must be two thirds the length of rgb888_pixels"
);
);
let
num_pixels
=
rgb888_pixels
.len
()
/
3
;
let
num_pixels
=
rgb888_pixels
.len
()
/
3
;
let
simd_chunks
=
num_pixels
/
SIMD_WIDTH
;
let
simd_chunks
=
num_pixels
/
SIMD_WIDTH
;
for
index
in
0
..
simd_chunks
{
for
index
in
0
..
simd_chunks
{
let
offset
=
index
*
SIMD_WIDTH
*
3
;
let
offset
=
index
*
SIMD_WIDTH
*
3
;
let
r
=
u8x16
::
from_slice
(
&
[
let
r
=
u8x16
::
from_slice
(
&
[
rgb888_pixels
[
offset
],
rgb888_pixels
[
offset
],
rgb888_pixels
[
offset
+
3
],
rgb888_pixels
[
offset
+
3
],
rgb888_pixels
[
offset
+
6
],
rgb888_pixels
[
offset
+
6
],
rgb888_pixels
[
offset
+
9
],
rgb888_pixels
[
offset
+
9
],
rgb888_pixels
[
offset
+
12
],
rgb888_pixels
[
offset
+
12
],
rgb888_pixels
[
offset
+
15
],
rgb888_pixels
[
offset
+
15
],
rgb888_pixels
[
offset
+
18
],
rgb888_pixels
[
offset
+
18
],
rgb888_pixels
[
offset
+
21
],
rgb888_pixels
[
offset
+
21
],
rgb888_pixels
[
offset
+
24
],
rgb888_pixels
[
offset
+
24
],
rgb888_pixels
[
offset
+
27
],
rgb888_pixels
[
offset
+
27
],
rgb888_pixels
[
offset
+
30
],
rgb888_pixels
[
offset
+
30
],
rgb888_pixels
[
offset
+
33
],
rgb888_pixels
[
offset
+
33
],
rgb888_pixels
[
offset
+
36
],
rgb888_pixels
[
offset
+
36
],
rgb888_pixels
[
offset
+
39
],
rgb888_pixels
[
offset
+
39
],
rgb888_pixels
[
offset
+
42
],
rgb888_pixels
[
offset
+
42
],
rgb888_pixels
[
offset
+
45
],
rgb888_pixels
[
offset
+
45
],
]);
]);
let
g
=
u8x16
::
from_slice
(
&
[
let
g
=
u8x16
::
from_slice
(
&
[
rgb888_pixels
[
offset
+
1
],
rgb888_pixels
[
offset
+
1
],
rgb888_pixels
[
offset
+
4
],
rgb888_pixels
[
offset
+
4
],
rgb888_pixels
[
offset
+
7
],
rgb888_pixels
[
offset
+
7
],
rgb888_pixels
[
offset
+
10
],
rgb888_pixels
[
offset
+
10
],
rgb888_pixels
[
offset
+
13
],
rgb888_pixels
[
offset
+
13
],
rgb888_pixels
[
offset
+
16
],
rgb888_pixels
[
offset
+
16
],
rgb888_pixels
[
offset
+
19
],
rgb888_pixels
[
offset
+
19
],
rgb888_pixels
[
offset
+
22
],
rgb888_pixels
[
offset
+
22
],
rgb888_pixels
[
offset
+
25
],
rgb888_pixels
[
offset
+
25
],
rgb888_pixels
[
offset
+
28
],
rgb888_pixels
[
offset
+
28
],
rgb888_pixels
[
offset
+
31
],
rgb888_pixels
[
offset
+
31
],
rgb888_pixels
[
offset
+
34
],
rgb888_pixels
[
offset
+
34
],
rgb888_pixels
[
offset
+
37
],
rgb888_pixels
[
offset
+
37
],
rgb888_pixels
[
offset
+
40
],
rgb888_pixels
[
offset
+
40
],
rgb888_pixels
[
offset
+
43
],
rgb888_pixels
[
offset
+
43
],
rgb888_pixels
[
offset
+
46
],
rgb888_pixels
[
offset
+
46
],
]);
]);
let
b
=
u8x16
::
from_slice
(
&
[
let
b
=
u8x16
::
from_slice
(
&
[
rgb888_pixels
[
offset
+
2
],
rgb888_pixels
[
offset
+
2
],
rgb888_pixels
[
offset
+
5
],
rgb888_pixels
[
offset
+
5
],
rgb888_pixels
[
offset
+
8
],
rgb888_pixels
[
offset
+
8
],
rgb888_pixels
[
offset
+
11
],
rgb888_pixels
[
offset
+
11
],
rgb888_pixels
[
offset
+
14
],
rgb888_pixels
[
offset
+
14
],
rgb888_pixels
[
offset
+
17
],
rgb888_pixels
[
offset
+
17
],
rgb888_pixels
[
offset
+
20
],
rgb888_pixels
[
offset
+
20
],
rgb888_pixels
[
offset
+
23
],
rgb888_pixels
[
offset
+
23
],
rgb888_pixels
[
offset
+
26
],
rgb888_pixels
[
offset
+
26
],
rgb888_pixels
[
offset
+
29
],
rgb888_pixels
[
offset
+
29
],
rgb888_pixels
[
offset
+
32
],
rgb888_pixels
[
offset
+
32
],
rgb888_pixels
[
offset
+
35
],
rgb888_pixels
[
offset
+
35
],
rgb888_pixels
[
offset
+
38
],
rgb888_pixels
[
offset
+
38
],
rgb888_pixels
[
offset
+
41
],
rgb888_pixels
[
offset
+
41
],
rgb888_pixels
[
offset
+
44
],
rgb888_pixels
[
offset
+
44
],
rgb888_pixels
[
offset
+
47
],
rgb888_pixels
[
offset
+
47
],
]);
]);
let
r_shifted_high
=
(
r
>>
1
)
&
u8x16
::
splat
(
0x7c
);
let
r_shifted_high
=
(
r
>>
1
)
&
u8x16
::
splat
(
0x7c
);
let
g_shifted_high
=
(
g
>>
6
)
&
u8x16
::
splat
(
0x03
);
let
g_shifted_high
=
(
g
>>
6
)
&
u8x16
::
splat
(
0x03
);
let
g_shifted_low
=
(
g
<<
2
)
&
u8x16
::
splat
(
0xe0
);
let
g_shifted_low
=
(
g
<<
2
)
&
u8x16
::
splat
(
0xe0
);
let
b_shifted
=
(
b
>>
3
)
&
u8x16
::
splat
(
0x3f
);
let
b_shifted
=
(
b
>>
3
)
&
u8x16
::
splat
(
0x3f
);
let
high_byte
=
u8x16
::
splat
(
0x80
)
|
r_shifted_high
|
g_shifted_high
;
let
high_byte
=
u8x16
::
splat
(
0x80
)
|
r_shifted_high
|
g_shifted_high
;
let
low_byte
=
g_shifted_low
|
b_shifted
;
let
low_byte
=
g_shifted_low
|
b_shifted
;
let
output_offset
=
index
*
SIMD_WIDTH
*
RGB1555_SIZE
;
let
output_offset
=
index
*
SIMD_WIDTH
*
RGB1555_SIZE
;
interleave_arrays
(
interleave_arrays
(
low_byte
.as_array
(),
low_byte
.as_array
(),
high_byte
.as_array
(),
high_byte
.as_array
(),
&
mut
rgb1555_pixels
[
output_offset
..
output_offset
+
SIMD_WIDTH
*
RGB1555_SIZE
],
&
mut
rgb1555_pixels
[
output_offset
..
output_offset
+
SIMD_WIDTH
*
RGB1555_SIZE
],
);
);
}
}
let
remainder
=
num_pixels
%
SIMD_WIDTH
;
let
remainder
=
num_pixels
%
SIMD_WIDTH
;
let
offset
=
simd_chunks
*
SIMD_WIDTH
*
RGB_SIZE
;
let
offset
=
simd_chunks
*
SIMD_WIDTH
*
RGB_SIZE
;
let
offset_rgb1555
=
simd_chunks
*
SIMD_WIDTH
*
RGB1555_SIZE
;
let
offset_rgb1555
=
simd_chunks
*
SIMD_WIDTH
*
RGB1555_SIZE
;
for
index
in
0
..
remainder
{
for
index
in
0
..
remainder
{
let
current_offset
=
offset
+
index
*
RGB_SIZE
;
let
current_offset
=
offset
+
index
*
RGB_SIZE
;
let
(
r
,
g
,
b
)
=
(
let
(
r
,
g
,
b
)
=
(
rgb888_pixels
[
current_offset
],
rgb888_pixels
[
current_offset
],
rgb888_pixels
[
current_offset
+
1
],
rgb888_pixels
[
current_offset
+
1
],
rgb888_pixels
[
current_offset
+
2
],
rgb888_pixels
[
current_offset
+
2
],
);
);
let
rgb1555
=
rgb888_to_rgb1555
(
r
,
g
,
b
);
let
rgb1555
=
rgb888_to_rgb1555
(
r
,
g
,
b
);
let
output_offset
=
offset_rgb1555
+
index
*
RGB1555_SIZE
;
let
output_offset
=
offset_rgb1555
+
index
*
RGB1555_SIZE
;
copy_fast
(
unsafe
{
&
rgb1555
,
copy_fast
(
&
mut
rgb1555_pixels
[
output_offset
..
output_offset
+
RGB1555_SIZE
],
&
rgb1555
,
RGB1555_SIZE
,
&
mut
rgb1555_pixels
[
output_offset
..
output_offset
+
RGB1555_SIZE
],
);
RGB1555_SIZE
,
}
);
}
}
}
#[cfg(test)]
}
mod
tests
{
use
super
::{
rgb888_to_rgb1555
,
rgb888_to_rgb1555_scalar
};
#[cfg(test)]
mod
tests
{
#[test]
use
super
::{
rgb888_to_rgb1555
,
rgb888_to_rgb1555_scalar
};
fn
test_rgb888_to_rgb1555
()
{
let
result
=
rgb888_to_rgb1555
(
255
,
0
,
0
);
#[test]
assert_eq!
(
result
,
[
0b00000000
,
0b11111100
]);
fn
test_rgb888_to_rgb1555
()
{
let
result
=
rgb888_to_rgb1555
(
255
,
0
,
0
);
let
result
=
rgb888_to_rgb1555
(
0
,
255
,
0
);
assert_eq!
(
result
,
[
0b00000000
,
0b11111100
]);
assert_eq!
(
result
,
[
0b11100000
,
0b10000011
]);
let
result
=
rgb888_to_rgb1555
(
0
,
255
,
0
);
let
result
=
rgb888_to_rgb1555
(
0
,
0
,
255
);
assert_eq!
(
result
,
[
0b11100000
,
0b10000011
]);
assert_eq!
(
result
,
[
0b00011111
,
0b10000000
]);
let
result
=
rgb888_to_rgb1555
(
0
,
0
,
255
);
let
result
=
rgb888_to_rgb1555
(
255
,
255
,
0
);
assert_eq!
(
result
,
[
0b00011111
,
0b10000000
]);
assert_eq!
(
result
,
[
0b11100000
,
0b11111111
]);
}
let
result
=
rgb888_to_rgb1555
(
255
,
255
,
0
);
assert_eq!
(
result
,
[
0b11100000
,
0b11111111
]);
#[test]
}
fn
test_rgb888_to_rgb1555_scalar
()
{
let
rgb888_pixels
:
Vec
<
u8
>
=
vec!
[
#[test]
255
,
000
,
000
,
// Red
fn
test_rgb888_to_rgb1555_scalar
()
{
000
,
255
,
000
,
// Green
let
rgb888_pixels
:
Vec
<
u8
>
=
vec!
[
000
,
000
,
255
,
// Blue
255
,
000
,
000
,
// Red
255
,
255
,
000
,
// Yellow
000
,
255
,
000
,
// Green
255
,
000
,
000
,
// Red
000
,
000
,
255
,
// Blue
000
,
255
,
000
,
// Green
255
,
255
,
000
,
// Yellow
000
,
000
,
255
,
// Blue
255
,
000
,
000
,
// Red
255
,
255
,
000
,
// Yellow
000
,
255
,
000
,
// Green
255
,
000
,
000
,
// Red
000
,
000
,
255
,
// Blue
000
,
255
,
000
,
// Green
255
,
255
,
000
,
// Yellow
000
,
000
,
255
,
// Blue
255
,
000
,
000
,
// Red
255
,
255
,
000
,
// Yellow
000
,
255
,
000
,
// Green
255
,
000
,
000
,
// Red
000
,
000
,
255
,
// Blue
000
,
255
,
000
,
// Green
255
,
255
,
000
,
// Yellow
000
,
000
,
255
,
// Blue
255
,
000
,
000
,
// Red
255
,
255
,
000
,
// Yellow
000
,
255
,
000
,
// Green
255
,
000
,
000
,
// Red
000
,
000
,
255
,
// Blue
020
,
020
,
200
,
// Blueish
255
,
255
,
000
,
// Yellow
];
255
,
000
,
000
,
// Red
let
mut
rgb1555_pixels
:
Vec
<
u8
>
=
vec!
[
0
;
36
];
020
,
020
,
200
,
// Blueish
];
rgb888_to_rgb1555_scalar
(
&
rgb888_pixels
,
&
mut
rgb1555_pixels
);
let
mut
rgb1555_pixels
:
Vec
<
u8
>
=
vec!
[
0
;
36
];
let
expected_rgb1555
:
Vec
<
u8
>
=
vec!
[
rgb888_to_rgb1555_scalar
(
&
rgb888_pixels
,
&
mut
rgb1555_pixels
);
0b00000000
,
0b11111100
,
// Red
0b11100000
,
0b10000011
,
// Green
let
expected_rgb1555
:
Vec
<
u8
>
=
vec!
[
0b00011111
,
0b10000000
,
// Blue
0b00000000
,
0b11111100
,
// Red
0b11100000
,
0b11111111
,
// Yellow
0b11100000
,
0b10000011
,
// Green
0b00000000
,
0b11111100
,
// Red
0b00011111
,
0b10000000
,
// Blue
0b11100000
,
0b10000011
,
// Green
0b11100000
,
0b11111111
,
// Yellow
0b00011111
,
0b10000000
,
// Blue
0b00000000
,
0b11111100
,
// Red
0b11100000
,
0b11111111
,
// Yellow
0b11100000
,
0b10000011
,
// Green
0b00000000
,
0b11111100
,
// Red
0b00011111
,
0b10000000
,
// Blue
0b11100000
,
0b10000011
,
// Green
0b11100000
,
0b11111111
,
// Yellow
0b00011111
,
0b10000000
,
// Blue
0b00000000
,
0b11111100
,
// Red
0b11100000
,
0b11111111
,
// Yellow
0b11100000
,
0b10000011
,
// Green
0b00000000
,
0b11111100
,
// Red
0b00011111
,
0b10000000
,
// Blue
0b11100000
,
0b10000011
,
// Green
0b11100000
,
0b11111111
,
// Yellow
0b00011111
,
0b10000000
,
// Blue
0b00000000
,
0b11111100
,
// Red
0b11100000
,
0b11111111
,
// Yellow
0b11100000
,
0b10000011
,
// Green
0b00000000
,
0b11111100
,
// Red
0b00011111
,
0b10000000
,
// Blue
0b01011001
,
0b10001000
,
// Blueish
0b11100000
,
0b11111111
,
// Yellow
];
0b00000000
,
0b11111100
,
// Red
0b01011001
,
0b10001000
,
// Blueish
assert_eq!
(
rgb1555_pixels
,
expected_rgb1555
);
];
}
assert_eq!
(
rgb1555_pixels
,
expected_rgb1555
);
#[test]
}
#[cfg(feature
=
"simd"
)]
fn
test_rgb888_to_rgb1555_simd
()
{
#[test]
use
super
::
rgb888_to_rgb1555_simd
;
#[cfg(feature
=
"simd"
)]
fn
test_rgb888_to_rgb1555_simd
()
{
let
rgb888_pixels
:
Vec
<
u8
>
=
vec!
[
use
super
::
rgb888_to_rgb1555_simd
;
255
,
000
,
000
,
// Red
000
,
255
,
000
,
// Green
let
rgb888_pixels
:
Vec
<
u8
>
=
vec!
[
000
,
000
,
255
,
// Blue
255
,
000
,
000
,
// Red
255
,
255
,
000
,
// Yellow
000
,
255
,
000
,
// Green
255
,
000
,
000
,
// Red
000
,
000
,
255
,
// Blue
000
,
255
,
000
,
// Green
255
,
255
,
000
,
// Yellow
000
,
000
,
255
,
// Blue
255
,
000
,
000
,
// Red
255
,
255
,
000
,
// Yellow
000
,
255
,
000
,
// Green
255
,
000
,
000
,
// Red
000
,
000
,
255
,
// Blue
000
,
255
,
000
,
// Green
255
,
255
,
000
,
// Yellow
000
,
000
,
255
,
// Blue
255
,
000
,
000
,
// Red
255
,
255
,
000
,
// Yellow
000
,
255
,
000
,
// Green
255
,
000
,
000
,
// Red
000
,
000
,
255
,
// Blue
000
,
255
,
000
,
// Green
255
,
255
,
000
,
// Yellow
000
,
000
,
255
,
// Blue
255
,
000
,
000
,
// Red
255
,
255
,
000
,
// Yellow
000
,
255
,
000
,
// Green
255
,
000
,
000
,
// Red
000
,
000
,
255
,
// Blue
020
,
020
,
200
,
// Blueish
255
,
255
,
000
,
// Yellow
];
255
,
000
,
000
,
// Red
let
mut
rgb1555_pixels
:
Vec
<
u8
>
=
vec!
[
0
;
36
];
020
,
020
,
200
,
// Blueish
];
rgb888_to_rgb1555_simd
(
&
rgb888_pixels
,
&
mut
rgb1555_pixels
);
let
mut
rgb1555_pixels
:
Vec
<
u8
>
=
vec!
[
0
;
36
];
let
expected_rgb1555
:
Vec
<
u8
>
=
vec!
[
rgb888_to_rgb1555_simd
(
&
rgb888_pixels
,
&
mut
rgb1555_pixels
);
0b00000000
,
0b11111100
,
// Red
0b11100000
,
0b10000011
,
// Green
let
expected_rgb1555
:
Vec
<
u8
>
=
vec!
[
0b00011111
,
0b10000000
,
// Blue
0b00000000
,
0b11111100
,
// Red
0b11100000
,
0b11111111
,
// Yellow
0b11100000
,
0b10000011
,
// Green
0b00000000
,
0b11111100
,
// Red
0b00011111
,
0b10000000
,
// Blue
0b11100000
,
0b10000011
,
// Green
0b11100000
,
0b11111111
,
// Yellow
0b00011111
,
0b10000000
,
// Blue
0b00000000
,
0b11111100
,
// Red
0b11100000
,
0b11111111
,
// Yellow
0b11100000
,
0b10000011
,
// Green
0b00000000
,
0b11111100
,
// Red
0b00011111
,
0b10000000
,
// Blue
0b11100000
,
0b10000011
,
// Green
0b11100000
,
0b11111111
,
// Yellow
0b00011111
,
0b10000000
,
// Blue
0b00000000
,
0b11111100
,
// Red
0b11100000
,
0b11111111
,
// Yellow
0b11100000
,
0b10000011
,
// Green
0b00000000
,
0b11111100
,
// Red
0b00011111
,
0b10000000
,
// Blue
0b11100000
,
0b10000011
,
// Green
0b11100000
,
0b11111111
,
// Yellow
0b00011111
,
0b10000000
,
// Blue
0b00000000
,
0b11111100
,
// Red
0b11100000
,
0b11111111
,
// Yellow
0b11100000
,
0b10000011
,
// Green
0b00000000
,
0b11111100
,
// Red
0b00011111
,
0b10000000
,
// Blue
0b01011001
,
0b10001000
,
// Blueish
0b11100000
,
0b11111111
,
// Yellow
];
0b00000000
,
0b11111100
,
// Red
0b01011001
,
0b10001000
,
// Blueish
assert_eq!
(
rgb1555_pixels
,
expected_rgb1555
);
];
}
}
assert_eq!
(
rgb1555_pixels
,
expected_rgb1555
);
}
}
This diff is collapsed.
Click to expand it.
src/util.rs
+
6
−
4
View file @
15828c2d
...
@@ -118,13 +118,15 @@ pub fn save_bmp(path: &str, pixels: &[u8], width: u32, height: u32) -> Result<()
...
@@ -118,13 +118,15 @@ pub fn save_bmp(path: &str, pixels: &[u8], width: u32, height: u32) -> Result<()
///
///
/// This function is optimized for performance and uses pointer-based
/// This function is optimized for performance and uses pointer-based
/// operations to copy the data as fast as possible.
/// operations to copy the data as fast as possible.
pub
unsafe
fn
copy_fast
(
src
:
&
[
u8
],
dst
:
&
mut
[
u8
],
count
:
usize
)
{
pub
fn
copy_fast
(
src
:
&
[
u8
],
dst
:
&
mut
[
u8
],
count
:
usize
)
{
debug_assert!
(
src
.len
()
>=
count
);
debug_assert!
(
src
.len
()
>=
count
);
debug_assert!
(
dst
.len
()
>=
count
);
debug_assert!
(
dst
.len
()
>=
count
);
let
src_ptr
=
src
.as_ptr
();
unsafe
{
let
dst_ptr
=
dst
.as_mut_ptr
();
let
src_ptr
=
src
.as_ptr
();
std
::
ptr
::
copy_nonoverlapping
(
src_ptr
,
dst_ptr
,
count
);
let
dst_ptr
=
dst
.as_mut_ptr
();
std
::
ptr
::
copy_nonoverlapping
(
src_ptr
,
dst_ptr
,
count
);
}
}
}
// Interleaves two arrays of bytes into a single array using
// Interleaves two arrays of bytes into a single array using
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment