Skip to content

Commit 29c875a

Browse files
authored
Merge pull request #46 from firefly-zero/image-v2
New image format (v2)
2 parents 9585e8c + 1939a61 commit 29c875a

File tree

2 files changed

+14
-103
lines changed

2 files changed

+14
-103
lines changed

src/graphics_canvas.mbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ struct Canvas(FixedArray[Byte]) derive(Default)
1010
///|
1111
/// Create a new blank canvas.
1212
pub fn Canvas::new(size : Size) -> Canvas {
13-
Canvas(Image::new(size, bpp=4).0)
13+
Canvas(Image::new(size).0)
1414
}
1515

1616
///|

src/graphics_image.mbt

Lines changed: 13 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -6,50 +6,25 @@ struct Image(FixedArray[Byte]) derive(Default)
66

77
///|
88
/// Create a new blank image.
9-
///
10-
/// By default the image uses 4 bits-per-pixel (`bpp`).
11-
/// The `bpp` must be either 1, 2, or 4.
12-
pub fn Image::new(size : Size, bpp? : Byte = 4) -> Image {
13-
guard bpp == 1 || bpp == 2 || bpp == 4 else { panic() }
14-
let header_size = 5 + bpp.to_int() * 2
15-
let body_size = size.w * size.h * bpp.to_int() / 8
9+
pub fn Image::new(size : Size) -> Image {
10+
let header_size = 4
11+
let body_size = size.w * size.h / 2
1612
let arr = FixedArray::make(header_size + body_size, Byte::default())
17-
arr[0] = 0x21 // magic number
18-
arr[1] = bpp
19-
arr[2] = size.w.to_byte()
20-
arr[3] = (size.w >> 8).to_byte()
21-
arr[4] = 255 // transparency
22-
for i in 0..<(2 * bpp.to_int()) {
23-
arr[5 + i] = (((i * 2) << 4) | (i * 2 + 1)).to_byte()
24-
}
13+
arr[0] = 0x22 // magic number
14+
arr[1] = size.w.to_byte()
15+
arr[2] = (size.w >> 8).to_byte()
16+
arr[3] = 0xff // no transparency
2517
Image(arr)
2618
}
2719

28-
///|
29-
test "new image has correct bpp" {
30-
inspect(Image::new(Size::new(20, 10), bpp=1).bpp(), content="1")
31-
inspect(Image::new(Size::new(20, 10), bpp=2).bpp(), content="2")
32-
inspect(Image::new(Size::new(20, 10), bpp=4).bpp(), content="4")
33-
}
34-
3520
///|
3621
test "new image has correct size" {
37-
inspect(Image::new(Size::new(20, 10), bpp=1).size(), content="{w: 20, h: 10}")
38-
inspect(Image::new(Size::new(20, 10), bpp=2).size(), content="{w: 20, h: 10}")
39-
inspect(Image::new(Size::new(20, 10), bpp=4).size(), content="{w: 20, h: 10}")
22+
inspect(Image::new(Size::new(20, 10)).size(), content="{w: 20, h: 10}")
4023
}
4124

4225
///|
4326
test "new image has correct pixel count" {
44-
inspect(Image::new(Size::new(20, 10), bpp=1).pixels(), content="200")
45-
inspect(Image::new(Size::new(20, 10), bpp=2).pixels(), content="200")
46-
inspect(Image::new(Size::new(20, 10), bpp=4).pixels(), content="200")
47-
}
48-
49-
///|
50-
/// Convert the `Image` to a `File`.
51-
pub fn Image::as_file(self : Image) -> File {
52-
File(self.0)
27+
inspect(Image::new(Size::new(20, 10)).pixels(), content="200")
5328
}
5429

5530
///|
@@ -74,16 +49,10 @@ pub fn Image::sub(self : Image, point : Point, size : Size) -> SubImage {
7449
}
7550
}
7651

77-
///|
78-
/// Bits per pixel. One of: 1, 2, or 4
79-
pub fn Image::bpp(self : Image) -> Int {
80-
self.0[1].to_int()
81-
}
82-
8352
///|
8453
/// The color used for transparency. If no transparency, returns `None`
8554
pub fn Image::transparency(self : Image) -> Color {
86-
match self.0[4] {
55+
match self.0[3] {
8756
_..<15 as c => Color::from_byte(c + 1)
8857
_ => Color::None
8958
}
@@ -103,14 +72,14 @@ pub fn Image::set_transparency(self : Image, color : Color) -> Unit {
10372
///|
10473
/// Returns the number of pixels the image has
10574
pub fn Image::pixels(self : Image) -> Int {
106-
let header_size = 5 + self.bpp() * 2
107-
(self.0.length() - header_size) * 8 / self.bpp()
75+
let header_size = 4
76+
(self.0.length() - header_size) * 2
10877
}
10978

11079
///|
11180
/// Returns the width of the image (in pixels).
11281
pub fn Image::width(self : Image) -> Int {
113-
self.0[2].to_int() | (self.0[3].to_int() << 8)
82+
self.0[1].to_int() | (self.0[2].to_int() << 8)
11483
}
11584

11685
///|
@@ -130,61 +99,3 @@ pub fn Image::size(self : Image) -> Size {
13099
_ as width => Size::new(width, self.pixels() / width)
131100
}
132101
}
133-
134-
///|
135-
/// Get a color from the image color palette.
136-
///
137-
/// Palette index must be between 0-15 (includesive),
138-
/// otherwise this function returns `Color::None`
139-
pub fn Image::get_color(self : Image, index : Byte) -> Color {
140-
if index > 15 {
141-
return Color::None
142-
}
143-
let mut val = self.0[5 + index.to_int() / 2]
144-
if index % 2 == 0 {
145-
val = val >> 4
146-
}
147-
val = val & 0b1111
148-
let transparentColor = self.0[4]
149-
if val == transparentColor {
150-
Color::None
151-
} else {
152-
Color::from_byte(val + 1)
153-
}
154-
}
155-
156-
///|
157-
/// Set color in the image color palette.
158-
///
159-
/// Palette index must be between 0-15 (includesive),
160-
/// otherwise this function is a no-op.
161-
pub fn Image::set_color(self : Image, index : Byte, color : Color) -> Unit {
162-
// ngl, this implementation looks kinda fishy.
163-
// needs testing, 'cause I ain't believing this is working
164-
if index > 15 || color is Color::None {
165-
return
166-
}
167-
let byte_index = 5 + index.to_int() / 2
168-
let mut val = self.0[byte_index]
169-
let color_val = color.to_byte() - 1
170-
if index % 2 == 0 {
171-
val = (color_val << 4) | (val & 0b1111)
172-
} else {
173-
val = color_val | (val & 0b1111_0000)
174-
}
175-
self.0[byte_index] = val
176-
}
177-
178-
///|
179-
/// Replace one color in the image's color palette with another.
180-
pub fn Image::replace_color(
181-
self : Image,
182-
old_color : Color,
183-
new_color : Color,
184-
) -> Unit {
185-
for index = (0 : Byte); index < 16; index = index + 1 {
186-
if self.get_color(index) == old_color {
187-
self.set_color(index, new_color)
188-
}
189-
}
190-
}

0 commit comments

Comments
 (0)