ggstd/image/image.rs
1// Copyright 2023 The rust-ggstd authors. All rights reserved.
2// Copyright 2009 The Go Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file.
5
6use super::color::{self, ColorTrait};
7use super::geom::{Point, Rectangle};
8
9/// Config holds an image's color model and dimensions.
10#[derive(Debug)]
11pub struct Config {
12    pub color_model: color::Model,
13    pub width: usize,
14    pub height: usize,
15}
16
17/// Image is a finite rectangular grid of color::Color values taken from a color
18/// model.
19pub trait Image {
20    /// color_model returns the Image's color model.
21    fn color_model(&self) -> color::Model;
22    /// bounds returns the domain for which At can return non-zero color::
23    /// The bounds do not necessarily contain the point (0, 0).
24    fn bounds(&self) -> &Rectangle;
25    /// at returns the color of the pixel at (x, y).
26    /// at(bounds().min.x, bounds().min.y) returns the upper-left pixel of the grid.
27    /// at(bounds().max.x-1, bounds().max.y-1) returns the lower-right one.
28    fn at(&self, x: isize, y: isize) -> color::Color;
29    // set color of the give pixel.  The color will be converted to the color model
30    // of the image if necessary.  The conversion may be lossy.
31    fn set(&mut self, x: isize, y: isize, c: &color::Color);
32    /// opaque scans the entire image and reports whether it is fully opaque.
33    fn opaque(&self) -> bool;
34    /// stride returns the pix stride (in bytes) between vertically adjacent pixels.
35    fn stride(&self) -> usize;
36    /// pix returns the image pixel data.  Format of the data depends on the image type.
37    fn pix(&self) -> &Vec<u8>;
38    /// bytes_per_pixel return how many bytes is used per pixel
39    fn bytes_per_pixel(&self) -> usize;
40
41    /// get_pix_mutable returns the image data for editing.
42    /// Format of the data depends on the image type.
43    fn get_pix_mutable(&mut self) -> &mut Vec<u8>;
44
45    /// deep_equal checks that two images are exactly the same
46    fn deep_equal(&self, other: &dyn Image) -> bool {
47        self.color_model() == other.color_model()
48            && self.bounds() == other.bounds()
49            && self.pix() == other.pix()
50    }
51
52    /// get_line_data returns data that encode one line of pixels.
53    fn get_line_data(&self, y: isize) -> &[u8] {
54        let b = self.bounds();
55        let offset = (y - b.min.y) as usize * self.stride();
56        &self.pix()[offset..offset + b.dx() * self.bytes_per_pixel()]
57    }
58}
59
60// // RGBA64Image is an Image whose pixels can be converted directly to a
61// // color::RGBA64.
62// type RGBA64Image interface {
63// 	// RGBA64At returns the RGBA64 color of the pixel at (x, y). It is
64// 	// equivalent to calling At(x, y).rgba() and converting the resulting
65// 	// 32-bit return values to a color::RGBA64, but it can avoid allocations
66// 	// from converting concrete color types to the color::Color interface type.
67// 	RGBA64At(x: isize, y: isize) color::RGBA64
68// 	Image
69// }
70
71// // PalettedImage is an image whose colors may come from a limited palette.
72// // If m is a PalettedImage and m.color_model() returns a color::Palette p,
73// // undefined.
74// type PalettedImage interface {
75// 	Image
76// }
77
78/// pixel_buffer_length returns the length of the [u8] typed pix slice field
79/// for the NewXxx functions.
80// Conceptually, this is just (bpp * width * height),
81// but this function panics if at least one of those is negative or if the
82// computation would overflow the isize type.
83//
84// This panics instead of returning an error because of backwards
85// compatibility. The NewXxx functions do not return an error.
86fn pixel_buffer_length(bytes_per_pixel: usize, r: &Rectangle, _image_type_name: &str) -> usize {
87    bytes_per_pixel * r.dx() * r.dy()
88}
89
90/// RGBA is an in-memory image whose At method returns color::RGBA values.
91#[derive(Debug)]
92pub struct RGBA {
93    /// pix holds the image's pixels, in R, G, B, A order. The pixel at
94    /// (x, y) starts at pix[(y-Rect.min.y)*stride + (x-Rect.min.x)*4].
95    pub pix: Vec<u8>,
96    /// stride is the pix stride (in bytes) between vertically adjacent pixels.
97    pub stride: usize,
98    /// rect is the image's bounds.
99    pub rect: Rectangle,
100}
101
102impl Image for RGBA {
103    fn color_model(&self) -> color::Model {
104        color::Model::RGBAModel
105    }
106
107    fn bounds(&self) -> &Rectangle {
108        &self.rect
109    }
110
111    fn opaque(&self) -> bool {
112        if self.rect.empty() {
113            return true;
114        }
115        let mut i0 = 3;
116        let mut i1 = self.rect.dx() * 4;
117        for _y in self.rect.min.y..self.rect.max.y {
118            let mut i = i0;
119            while i < i1 {
120                if self.pix[i] != 0xff {
121                    return false;
122                }
123                i += 4;
124            }
125            i0 += self.stride;
126            i1 += self.stride;
127        }
128        true
129    }
130
131    fn stride(&self) -> usize {
132        self.stride
133    }
134
135    fn pix(&self) -> &Vec<u8> {
136        &self.pix
137    }
138
139    fn get_pix_mutable(&mut self) -> &mut Vec<u8> {
140        &mut self.pix
141    }
142
143    fn at(&self, x: isize, y: isize) -> color::Color {
144        color::Color::RGBA(self.rgba_at(x, y))
145    }
146
147    fn set(&mut self, x: isize, y: isize, c: &color::Color) {
148        if let color::Color::RGBA(c) = c {
149            self.set_rbga(x, y, c);
150        } else {
151            self.set_rbga(x, y, &color::RGBA::new_from(c));
152        };
153    }
154
155    fn bytes_per_pixel(&self) -> usize {
156        4
157    }
158
159    // fn (p *RGBA) RGBA64At(x: isize, y: isize) color::RGBA64 {
160    // 	if !Point::new(x, y).inside(&self.rect) {
161    // 		return color::RGBA64{}
162    // 	}
163    // 	let i = self.pix_offset(x, y);
164    // 	s := self.pix[i..i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
165    // 	r := uint16(s[0])
166    // 	g := uint16(s[1])
167    // 	b := uint16(s[2])
168    // 	a := uint16(s[3])
169    // 	return color::RGBA64{
170    // 		(r << 8) | r,
171    // 		(g << 8) | g,
172    // 		(b << 8) | b,
173    // 		(a << 8) | a,
174    // 	}
175    // }
176}
177
178impl RGBA {
179    /// new returns a new RGBA image with the given bounds.
180    pub fn new(r: &Rectangle) -> Self {
181        Self {
182            pix: vec![0; pixel_buffer_length(4, r, "RGBA")],
183            stride: 4 * r.dx(),
184            rect: *r,
185        }
186    }
187
188    pub fn rgba_at(&self, x: isize, y: isize) -> color::RGBA {
189        if !(Point::new(x, y).inside(&self.rect)) {
190            return color::RGBA::new(0, 0, 0, 0);
191        }
192        let i = self.pix_offset(x, y);
193        let s = &self.pix[i..i + 4];
194        color::RGBA::new(s[0], s[1], s[2], s[3])
195    }
196
197    // fn (p *RGBA) SetRGBA64(x: isize, y: isize, c color::RGBA64) {
198    // 	if !Point::new(x, y).inside(&self.rect) {
199    // 		return
200    // 	}
201    // 	let i = self.pix_offset(x, y);
202    // 	s := self.pix[i..i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
203    // 	s[0] = u8(c.r >> 8)
204    // 	s[1] = u8(c.g >> 8)
205    // 	s[2] = u8(c.b >> 8)
206    // 	s[3] = u8(c.a >> 8)
207    // }
208
209    pub fn set_rbga(&mut self, x: isize, y: isize, c: &color::RGBA) {
210        if !(Point::new(x, y).inside(&self.rect)) {
211            return;
212        }
213        let i = self.pix_offset(x, y);
214        let s = &mut self.pix[i..i + 4];
215        s[0] = c.r;
216        s[1] = c.g;
217        s[2] = c.b;
218        s[3] = c.a;
219    }
220
221    // // SubImage returns an image representing the portion of the image p visible
222    // // through r. The returned value shares pixels with the original image.
223    // fn (p *RGBA) SubImage(r Rectangle) Image {
224    // 	r = r.intersect(self.rect)
225    // 	// If r1 and r2 are Rectangles, r1.intersect(r2) is not guaranteed to be inside
226    // 	// either r1 or r2 if the intersection is empty. Without explicitly checking for
227    // 	// this, the pix[i:] expression below can panic.
228    // 	if r.Empty() {
229    // 		return &RGBA{}
230    // 	}
231    // 	let i = self.pix_offset(r.min.x, r.min.y)
232    // 	return &RGBA{
233    // 		pix:    self.pix[i:],
234    // 		stride: self.stride,
235    // 		Rect:   r,
236    // 	}
237    // }
238
239    /// pix_offset returns the index of the first element of pix that corresponds to
240    /// the pixel at (x, y).
241    pub fn pix_offset(&self, x: isize, y: isize) -> usize {
242        (y - self.rect.min.y) as usize * self.stride + (x - self.rect.min.x) as usize * 4
243    }
244}
245
246/// RGBA64 is an in-memory image whose At method returns color::RGBA64 values.
247#[derive(Debug)]
248pub struct RGBA64 {
249    // pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
250    // (x, y) starts at pix[(y-Rect.min.y)*stride + (x-Rect.min.x)*8].
251    pub pix: Vec<u8>,
252    /// stride is the pix stride (in bytes) between vertically adjacent pixels.
253    pub stride: usize,
254    /// rect is the image's bounds.
255    rect: Rectangle,
256}
257
258impl Image for RGBA64 {
259    fn color_model(&self) -> color::Model {
260        color::Model::RGBA64Model
261    }
262
263    fn bounds(&self) -> &Rectangle {
264        &self.rect
265    }
266
267    fn at(&self, x: isize, y: isize) -> color::Color {
268        color::Color::RGBA64(self.rgba64_at(x, y))
269    }
270
271    fn set(&mut self, x: isize, y: isize, c: &color::Color) {
272        if let color::Color::RGBA64(c) = c {
273            self.set_rgba64(x, y, c);
274        } else {
275            self.set_rgba64(x, y, &color::RGBA64::new_from(c));
276        };
277    }
278
279    // opaque scans the entire image and reports whether it is fully opaque.
280    fn opaque(&self) -> bool {
281        if self.rect.empty() {
282            return true;
283        }
284        let (mut i0, mut i1) = (6, self.rect.dx() * 8);
285        for _y in self.rect.min.y..self.rect.max.y {
286            let mut i = i0;
287            while i < i1 {
288                if self.pix[i] != 0xff || self.pix[i + 1] != 0xff {
289                    return false;
290                }
291                i += 8;
292            }
293            i0 += self.stride;
294            i1 += self.stride;
295        }
296        true
297    }
298
299    fn stride(&self) -> usize {
300        self.stride
301    }
302
303    fn pix(&self) -> &Vec<u8> {
304        &self.pix
305    }
306
307    fn get_pix_mutable(&mut self) -> &mut Vec<u8> {
308        &mut self.pix
309    }
310
311    fn bytes_per_pixel(&self) -> usize {
312        8
313    }
314}
315
316impl RGBA64 {
317    /// new returns a new RGBA64 image with the given bounds.
318    pub fn new(r: &Rectangle) -> Self {
319        Self {
320            pix: vec![0; pixel_buffer_length(8, r, "RGBA64")],
321            stride: 8 * r.dx(),
322            rect: *r,
323        }
324    }
325
326    /// pix_offset returns the index of the first element of pix that corresponds to
327    /// the pixel at (x, y).
328    pub fn pix_offset(&self, x: isize, y: isize) -> usize {
329        (y - self.rect.min.y) as usize * self.stride + (x - self.rect.min.x) as usize * 8
330    }
331
332    fn rgba64_at(&self, x: isize, y: isize) -> color::RGBA64 {
333        if !(Point::new(x, y).inside(&self.rect)) {
334            return color::RGBA64::new(0, 0, 0, 0);
335        }
336        let i = self.pix_offset(x, y);
337        let s = &self.pix[i..i + 8];
338        color::RGBA64::new(
339            ((s[0] as u16) << 8) | (s[1] as u16),
340            ((s[2] as u16) << 8) | (s[3] as u16),
341            ((s[4] as u16) << 8) | (s[5] as u16),
342            ((s[6] as u16) << 8) | (s[7] as u16),
343        )
344    }
345
346    fn set_rgba64(&mut self, x: isize, y: isize, c: &color::RGBA64) {
347        if !(Point::new(x, y).inside(&self.rect)) {
348            return;
349        }
350        let i = self.pix_offset(x, y);
351        let s = &mut self.pix[i..i + 8];
352        s[0] = (c.r >> 8) as u8;
353        s[1] = c.r as u8;
354        s[2] = (c.g >> 8) as u8;
355        s[3] = c.g as u8;
356        s[4] = (c.b >> 8) as u8;
357        s[5] = c.b as u8;
358        s[6] = (c.a >> 8) as u8;
359        s[7] = c.a as u8;
360    }
361}
362
363// // SubImage returns an image representing the portion of the image p visible
364// // through r. The returned value shares pixels with the original image.
365// fn (p *RGBA64) SubImage(r Rectangle) Image {
366// 	r = r.intersect(self.rect)
367// 	// If r1 and r2 are Rectangles, r1.intersect(r2) is not guaranteed to be inside
368// 	// either r1 or r2 if the intersection is empty. Without explicitly checking for
369// 	// this, the pix[i:] expression below can panic.
370// 	if r.Empty() {
371// 		return &RGBA64{}
372// 	}
373// 	let i = self.pix_offset(r.min.x, r.min.y)
374// 	return &RGBA64{
375// 		pix:    self.pix[i:],
376// 		stride: self.stride,
377// 		Rect:   r,
378// 	}
379// }
380
381/// NRGBA is an in-memory image whose At method returns color::NRGBA values.
382#[derive(Debug)]
383pub struct NRGBA {
384    /// pix holds the image's pixels, in R, G, B, A order. The pixel at
385    /// (x, y) starts at pix[(y-Rect.min.y)*stride + (x-Rect.min.x)*4].
386    pub pix: Vec<u8>,
387    /// stride is the pix stride (in bytes) between vertically adjacent pixels.
388    pub stride: usize,
389    /// rect is the image's bounds.
390    pub rect: Rectangle,
391}
392
393impl Image for NRGBA {
394    fn color_model(&self) -> color::Model {
395        color::Model::NRGBAModel
396    }
397
398    fn bounds(&self) -> &Rectangle {
399        &self.rect
400    }
401
402    /// opaque scans the entire image and reports whether it is fully opaque.
403    fn opaque(&self) -> bool {
404        if self.rect.empty() {
405            return true;
406        }
407        let mut i0 = 3;
408        let mut i1 = self.rect.dx() * 4;
409        for _y in self.rect.min.y..self.rect.max.y {
410            let mut i = i0;
411            while i < i1 {
412                if self.pix[i] != 0xff {
413                    return false;
414                }
415                i += 4;
416            }
417            i0 += self.stride;
418            i1 += self.stride;
419        }
420        true
421    }
422
423    fn stride(&self) -> usize {
424        self.stride
425    }
426
427    fn pix(&self) -> &Vec<u8> {
428        &self.pix
429    }
430
431    fn get_pix_mutable(&mut self) -> &mut Vec<u8> {
432        &mut self.pix
433    }
434
435    fn at(&self, x: isize, y: isize) -> color::Color {
436        color::Color::NRGBA(self.nrgba_at(x, y))
437    }
438
439    fn set(&mut self, x: isize, y: isize, c: &color::Color) {
440        if let color::Color::NRGBA(c) = c {
441            self.set_nrgba(x, y, c);
442        } else {
443            self.set_nrgba(x, y, &color::NRGBA::new_from(c));
444        };
445    }
446
447    fn bytes_per_pixel(&self) -> usize {
448        4
449    }
450}
451
452impl NRGBA {
453    /// new returns a new NRGBA image with the given bounds.
454    pub fn new(r: &Rectangle) -> Self {
455        Self {
456            pix: vec![0; pixel_buffer_length(4, r, "NRGBA")],
457            stride: 4 * r.dx(),
458            rect: *r,
459        }
460    }
461
462    // fn RGBA64At(&self, x: isize, y: isize) color::RGBA64 {
463    // 	r, g, b, a := self.nrgba_at(x, y).rgba()
464    // 	return color::RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
465    // }
466
467    fn nrgba_at(&self, x: isize, y: isize) -> color::NRGBA {
468        if !(Point::new(x, y).inside(&self.rect)) {
469            return color::NRGBA::new(0, 0, 0, 0);
470        }
471        let i = self.pix_offset(x, y);
472        let s = &self.pix[i..i + 4];
473        color::NRGBA::new(s[0], s[1], s[2], s[3])
474    }
475
476    /// pix_offset returns the index of the first element of pix that corresponds to
477    /// the pixel at (x, y).
478    pub fn pix_offset(&self, x: isize, y: isize) -> usize {
479        (y - self.rect.min.y) as usize * self.stride + (x - self.rect.min.x) as usize * 4
480    }
481
482    pub fn set_nrgba(&mut self, x: isize, y: isize, c: &color::NRGBA) {
483        if !(Point::new(x, y).inside(&self.rect)) {
484            return;
485        }
486        let i = self.pix_offset(x, y);
487        self.pix[i] = c.r;
488        self.pix[i + 1] = c.g;
489        self.pix[i + 2] = c.b;
490        self.pix[i + 3] = c.a;
491    }
492    // fn SetRGBA64(&self, x: isize, y: isize, c color::RGBA64) {
493    // 	if !Point::new(x, y).inside(&self.rect) {
494    // 		return
495    // 	}
496    // 	r, g, b, a := uint32(c.r), uint32(c.g), uint32(c.b), uint32(c.a)
497    // 	if (a != 0) && (a != 0xffff) {
498    // 		r = (r * 0xffff) / a
499    // 		g = (g * 0xffff) / a
500    // 		b = (b * 0xffff) / a
501    // 	}
502    // 	let i = self.pix_offset(x, y);
503    // 	s := self.pix[i..i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
504    // 	s[0] = u8(r >> 8)
505    // 	s[1] = u8(g >> 8)
506    // 	s[2] = u8(b >> 8)
507    // 	s[3] = u8(a >> 8)
508    // }
509
510    // // SubImage returns an image representing the portion of the image p visible
511    // // through r. The returned value shares pixels with the original image.
512    // fn SubImage(&self, r Rectangle) Image {
513    // 	r = r.intersect(self.rect)
514    // 	// If r1 and r2 are Rectangles, r1.intersect(r2) is not guaranteed to be inside
515    // 	// either r1 or r2 if the intersection is empty. Without explicitly checking for
516    // 	// this, the pix[i:] expression below can panic.
517    // 	if r.Empty() {
518    // 		return &NRGBA{}
519    // 	}
520    // 	let i = self.pix_offset(r.min.x, r.min.y)
521    // 	return &NRGBA{
522    // 		pix:    self.pix[i:],
523    // 		stride: self.stride,
524    // 		Rect:   r,
525    // 	}
526    // }
527}
528
529/// NRGBA64 is an in-memory image whose At method returns color::NRGBA64 values.
530#[derive(Debug)]
531pub struct NRGBA64 {
532    // pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
533    // (x, y) starts at pix[(y-Rect.min.y)*stride + (x-Rect.min.x)*8].
534    pub pix: Vec<u8>,
535    /// stride is the pix stride (in bytes) between vertically adjacent pixels.
536    pub stride: usize,
537    /// rect is the image's bounds.
538    rect: Rectangle,
539}
540
541impl Image for NRGBA64 {
542    fn color_model(&self) -> color::Model {
543        color::Model::NRGBA64Model
544    }
545
546    fn bounds(&self) -> &Rectangle {
547        &self.rect
548    }
549
550    // fn at(&self, x: isize, y: isize) -> color::Color {
551    //     color::Color::RGBA64(self.rgba64_at(x, y))
552    // }
553
554    fn set(&mut self, x: isize, y: isize, c: &color::Color) {
555        if let color::Color::NRGBA64(c) = c {
556            self.set_nrgba64(x, y, c);
557        } else {
558            self.set_nrgba64(x, y, &color::NRGBA64::new_from(c));
559        };
560    }
561
562    // // opaque scans the entire image and reports whether it is fully opaque.
563    // fn opaque(&self) -> bool {
564    //     if self.rect.empty() {
565    //         return true;
566    //     }
567    //     let (mut i0, mut i1) = (6, self.rect.dx() * 8);
568    //     for _y in self.rect.min.y..self.rect.max.y {
569    //         let mut i = i0;
570    //         while i < i1 {
571    //             if self.pix[i ] != 0xff || self.pix[i + 1] != 0xff {
572    //                 return false;
573    //             }
574    //             i += 8;
575    //         }
576    //         i0 += self.stride;
577    //         i1 += self.stride;
578    //     }
579    //     return true;
580    // }
581
582    fn stride(&self) -> usize {
583        self.stride
584    }
585
586    fn pix(&self) -> &Vec<u8> {
587        &self.pix
588    }
589
590    fn get_pix_mutable(&mut self) -> &mut Vec<u8> {
591        &mut self.pix
592    }
593
594    fn at(&self, x: isize, y: isize) -> color::Color {
595        color::Color::NRGBA64(self.nrgba64_at(x, y))
596    }
597
598    fn opaque(&self) -> bool {
599        if self.rect.empty() {
600            return true;
601        }
602        let (mut i0, mut i1) = (6, self.rect.dx() * 8);
603        for _y in self.rect.min.y..self.rect.max.y {
604            let mut i = i0;
605            while i < i1 {
606                if self.pix[i] != 0xff || self.pix[i + 1] != 0xff {
607                    return false;
608                }
609                i += 8;
610            }
611            i0 += self.stride;
612            i1 += self.stride;
613        }
614        true
615    }
616
617    fn bytes_per_pixel(&self) -> usize {
618        8
619    }
620}
621
622impl NRGBA64 {
623    /// new returns a new NRGBA64 image with the given bounds.
624    pub fn new(r: &Rectangle) -> Self {
625        Self {
626            pix: vec![0; pixel_buffer_length(8, r, "NRGBA64")],
627            stride: 8 * r.dx(),
628            rect: *r,
629        }
630    }
631
632    fn set_nrgba64(&mut self, x: isize, y: isize, c: &color::NRGBA64) {
633        if !(Point::new(x, y).inside(&self.rect)) {
634            return;
635        }
636        let i = self.pix_offset(x, y);
637        let s = &mut self.pix[i..i + 8];
638        s[0] = (c.r >> 8) as u8;
639        s[1] = c.r as u8;
640        s[2] = (c.g >> 8) as u8;
641        s[3] = c.g as u8;
642        s[4] = (c.b >> 8) as u8;
643        s[5] = c.b as u8;
644        s[6] = (c.a >> 8) as u8;
645        s[7] = c.a as u8;
646    }
647
648    /// pix_offset returns the index of the first element of pix that corresponds to
649    /// the pixel at (x, y).
650    pub fn pix_offset(&self, x: isize, y: isize) -> usize {
651        (y - self.rect.min.y) as usize * self.stride + (x - self.rect.min.x) as usize * 8
652    }
653
654    // fn (p *NRGBA64) RGBA64At(x: isize, y: isize) color::RGBA64 {
655    // 	r, g, b, a := self.nrgba64_at(x, y).rgba()
656    // 	return color::RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
657    // }
658
659    fn nrgba64_at(&self, x: isize, y: isize) -> color::NRGBA64 {
660        if !(Point::new(x, y).inside(&self.rect)) {
661            return color::NRGBA64::new(0, 0, 0, 0);
662        }
663        let i = self.pix_offset(x, y);
664        let s = &self.pix[i..i + 8];
665        color::NRGBA64::new(
666            (s[0] as u16) << 8 | (s[1] as u16),
667            (s[2] as u16) << 8 | (s[3] as u16),
668            (s[4] as u16) << 8 | (s[5] as u16),
669            (s[6] as u16) << 8 | (s[7] as u16),
670        )
671    }
672
673    // fn (p *NRGBA64) SetRGBA64(x: isize, y: isize, c color::RGBA64) {
674    // 	if !Point::new(x, y).inside(&self.rect) {
675    // 		return
676    // 	}
677    // 	r, g, b, a := uint32(c.r), uint32(c.g), uint32(c.b), uint32(c.a)
678    // 	if (a != 0) && (a != 0xffff) {
679    // 		r = (r * 0xffff) / a
680    // 		g = (g * 0xffff) / a
681    // 		b = (b * 0xffff) / a
682    // 	}
683    // 	let i = self.pix_offset(x, y);
684    // 	s := self.pix[i..i+8 : i+8] // Small cap improves performance, see https://golang.org/issue/27857
685    // 	s[0] = u8(r >> 8)
686    // 	s[1] = u8(r)
687    // 	s[2] = u8(g >> 8)
688    // 	s[3] = u8(g)
689    // 	s[4] = u8(b >> 8)
690    // 	s[5] = u8(b)
691    // 	s[6] = u8(a >> 8)
692    // 	s[7] = u8(a)
693    // }
694
695    // // SubImage returns an image representing the portion of the image p visible
696    // // through r. The returned value shares pixels with the original image.
697    // fn (p *NRGBA64) SubImage(r Rectangle) Image {
698    // 	r = r.intersect(self.rect)
699    // 	// If r1 and r2 are Rectangles, r1.intersect(r2) is not guaranteed to be inside
700    // 	// either r1 or r2 if the intersection is empty. Without explicitly checking for
701    // 	// this, the pix[i:] expression below can panic.
702    // 	if r.Empty() {
703    // 		return &NRGBA64{}
704    // 	}
705    // 	let i = self.pix_offset(r.min.x, r.min.y)
706    // 	return &NRGBA64{
707    // 		pix:    self.pix[i:],
708    // 		stride: self.stride,
709    // 		Rect:   r,
710    // 	}
711    // }
712}
713
714/// Alpha is an in-memory image whose At method returns color::Alpha values.
715#[derive(Debug)]
716pub struct Alpha {
717    // pix holds the image's pixels, as alpha values. The pixel at
718    // (x, y) starts at pix[(y-Rect.min.y)*stride + (x-Rect.min.x)*1].
719    pub pix: Vec<u8>,
720    /// stride is the pix stride (in bytes) between vertically adjacent pixels.
721    pub stride: usize,
722    /// rect is the image's bounds.
723    rect: Rectangle,
724}
725
726impl Image for Alpha {
727    fn color_model(&self) -> color::Model {
728        color::Model::AlphaModel
729    }
730
731    fn bounds(&self) -> &Rectangle {
732        &self.rect
733    }
734
735    fn at(&self, x: isize, y: isize) -> color::Color {
736        color::Color::Alpha(self.alpha_at(x, y))
737    }
738
739    fn set(&mut self, x: isize, y: isize, c: &color::Color) {
740        if let color::Color::Alpha(c) = c {
741            self.set_alpha(x, y, c);
742        } else {
743            self.set_alpha(x, y, &color::Alpha::new_from(c));
744        };
745    }
746
747    fn opaque(&self) -> bool {
748        if self.rect.empty() {
749            return true;
750        }
751        let (mut i0, mut i1) = (0, self.rect.dx());
752        for _y in self.rect.min.y..self.rect.max.y {
753            for i in i0..i1 {
754                if self.pix[i] != 0xff {
755                    return false;
756                }
757            }
758            i0 += self.stride;
759            i1 += self.stride;
760        }
761        true
762    }
763
764    fn stride(&self) -> usize {
765        self.stride
766    }
767
768    fn pix(&self) -> &Vec<u8> {
769        &self.pix
770    }
771
772    fn get_pix_mutable(&mut self) -> &mut Vec<u8> {
773        &mut self.pix
774    }
775
776    fn bytes_per_pixel(&self) -> usize {
777        1
778    }
779}
780
781impl Alpha {
782    /// new returns a new Alpha image with the given bounds.
783    pub fn new(r: &Rectangle) -> Self {
784        Self {
785            pix: vec![0; pixel_buffer_length(1, r, "Alpha")],
786            stride: r.dx(),
787            rect: *r,
788        }
789    }
790
791    fn alpha_at(&self, x: isize, y: isize) -> color::Alpha {
792        if !(Point::new(x, y).inside(&self.rect)) {
793            return color::Alpha::new(0);
794        }
795        let i = self.pix_offset(x, y);
796        color::Alpha::new(self.pix[i])
797    }
798
799    /// pix_offset returns the index of the first element of pix that corresponds to
800    /// the pixel at (x, y).
801    pub fn pix_offset(&self, x: isize, y: isize) -> usize {
802        (y - self.rect.min.y) as usize * self.stride + (x - self.rect.min.x) as usize
803    }
804
805    // fn RGBA64At(&self, x: isize, y: isize) color::RGBA64 {
806    // 	a := uint16(self.alpha_at(x, y).a)
807    // 	a |= a << 8
808    // 	return color::RGBA64{a, a, a, a}
809    // }
810
811    // fn SetRGBA64(&self, x: isize, y: isize, c color::RGBA64) {
812    // 	if !Point::new(x, y).inside(&self.rect) {
813    // 		return
814    // 	}
815    // 	let i = self.pix_offset(x, y);
816    // 	self.pix[i] = u8(c.a >> 8)
817    // }
818
819    fn set_alpha(&mut self, x: isize, y: isize, c: &color::Alpha) {
820        if !(Point::new(x, y).inside(&self.rect)) {
821            return;
822        }
823        let i = self.pix_offset(x, y);
824        self.pix[i] = c.a;
825    }
826
827    // // SubImage returns an image representing the portion of the image p visible
828    // // through r. The returned value shares pixels with the original image.
829    // fn SubImage(&self, r Rectangle) Image {
830    // 	r = r.intersect(self.rect)
831    // 	// If r1 and r2 are Rectangles, r1.intersect(r2) is not guaranteed to be inside
832    // 	// either r1 or r2 if the intersection is empty. Without explicitly checking for
833    // 	// this, the pix[i:] expression below can panic.
834    // 	if r.Empty() {
835    // 		return &Alpha{}
836    // 	}
837    // 	let i = self.pix_offset(r.min.x, r.min.y)
838    // 	return &Alpha{
839    // 		pix:    self.pix[i:],
840    // 		stride: self.stride,
841    // 		Rect:   r,
842    // 	}
843    // }
844}
845
846/// Alpha16 is an in-memory image whose At method returns color::Alpha16 values.
847#[derive(Debug)]
848pub struct Alpha16 {
849    // pix holds the image's pixels, as alpha values. The pixel at
850    // (x, y) starts at pix[(y-Rect.min.y)*stride + (x-Rect.min.x)*1].
851    pub pix: Vec<u8>,
852    /// stride is the pix stride (in bytes) between vertically adjacent pixels.
853    pub stride: usize,
854    /// rect is the image's bounds.
855    rect: Rectangle,
856}
857
858impl Image for Alpha16 {
859    fn color_model(&self) -> color::Model {
860        color::Model::Alpha16Model
861    }
862
863    fn bounds(&self) -> &Rectangle {
864        &self.rect
865    }
866
867    fn at(&self, x: isize, y: isize) -> color::Color {
868        color::Color::Alpha16(self.alpha16_at(x, y))
869    }
870
871    fn set(&mut self, x: isize, y: isize, c: &color::Color) {
872        if let color::Color::Alpha16(c) = c {
873            self.set_alpha16(x, y, c);
874        } else {
875            self.set_alpha16(x, y, &color::Alpha16::new_from(c));
876        };
877    }
878
879    fn opaque(&self) -> bool {
880        if self.rect.empty() {
881            return true;
882        }
883        let (mut i0, mut i1) = (0, self.rect.dx() * 2);
884        for _y in self.rect.min.y..self.rect.max.y {
885            let mut i = i0;
886            while i < i1 {
887                if self.pix[i] != 0xff || self.pix[i + 1] != 0xff {
888                    return false;
889                }
890                i += 2;
891            }
892            i0 += self.stride;
893            i1 += self.stride;
894        }
895        true
896    }
897
898    fn stride(&self) -> usize {
899        self.stride
900    }
901
902    fn pix(&self) -> &Vec<u8> {
903        &self.pix
904    }
905
906    fn get_pix_mutable(&mut self) -> &mut Vec<u8> {
907        &mut self.pix
908    }
909
910    fn bytes_per_pixel(&self) -> usize {
911        2
912    }
913}
914
915impl Alpha16 {
916    /// new returns a new Alpha16 image with the given bounds.
917    pub fn new(r: &Rectangle) -> Self {
918        Self {
919            pix: vec![0; pixel_buffer_length(2, r, "Alpha16")],
920            stride: 2 * r.dx(),
921            rect: *r,
922        }
923    }
924
925    fn alpha16_at(&self, x: isize, y: isize) -> color::Alpha16 {
926        if !(Point::new(x, y).inside(&self.rect)) {
927            return color::Alpha16::new(0);
928        }
929        let i = self.pix_offset(x, y);
930        color::Alpha16::new((self.pix[i] as u16) << 8 | (self.pix[i + 1] as u16))
931    }
932
933    /// pix_offset returns the index of the first element of pix that corresponds to
934    /// the pixel at (x, y).
935    pub fn pix_offset(&self, x: isize, y: isize) -> usize {
936        (y - self.rect.min.y) as usize * self.stride + (x - self.rect.min.x) as usize * 2
937    }
938
939    // fn (p *Alpha16) RGBA64At(x: isize, y: isize) color::RGBA64 {
940    // 	a := self.Alpha16At(x, y).a
941    // 	return color::RGBA64{a, a, a, a}
942    // }
943
944    // fn (p *Alpha16) SetRGBA64(x: isize, y: isize, c color::RGBA64) {
945    // 	if !Point::new(x, y).inside(&self.rect) {
946    // 		return
947    // 	}
948    // 	let i = self.pix_offset(x, y);
949    // 	self.pix[i+0] = u8(c.a >> 8)
950    // 	self.pix[i+1] = u8(c.a)
951    // }
952
953    fn set_alpha16(&mut self, x: isize, y: isize, c: &color::Alpha16) {
954        if !(Point::new(x, y).inside(&self.rect)) {
955            return;
956        }
957        let i = self.pix_offset(x, y);
958        self.pix[i] = (c.a >> 8) as u8;
959        self.pix[i + 1] = (c.a) as u8;
960    }
961
962    // // SubImage returns an image representing the portion of the image p visible
963    // // through r. The returned value shares pixels with the original image.
964    // fn (p *Alpha16) SubImage(r Rectangle) Image {
965    // 	r = r.intersect(self.rect)
966    // 	// If r1 and r2 are Rectangles, r1.intersect(r2) is not guaranteed to be inside
967    // 	// either r1 or r2 if the intersection is empty. Without explicitly checking for
968    // 	// this, the pix[i:] expression below can panic.
969    // 	if r.Empty() {
970    // 		return &Alpha16{}
971    // 	}
972    // 	let i = self.pix_offset(r.min.x, r.min.y)
973    // 	return &Alpha16{
974    // 		pix:    self.pix[i:],
975    // 		stride: self.stride,
976    // 		Rect:   r,
977    // 	}
978    // }
979}
980
981/// Gray is an in-memory image whose At method returns color::Gray values.
982#[derive(Debug)]
983pub struct Gray {
984    /// pix holds the image's pixels, as gray values. The pixel at
985    /// (x, y) starts at pix[(y-Rect.min.y)*stride + (x-Rect.min.x)*1].
986    pub pix: Vec<u8>,
987    /// stride is the pix stride (in bytes) between vertically adjacent pixels.
988    pub stride: usize,
989    /// rect is the image's bounds.
990    rect: Rectangle,
991}
992
993impl Image for Gray {
994    fn color_model(&self) -> color::Model {
995        color::Model::GrayModel
996    }
997
998    fn bounds(&self) -> &Rectangle {
999        &self.rect
1000    }
1001
1002    /// opaque scans the entire image and reports whether it is fully opaque.
1003    fn opaque(&self) -> bool {
1004        true
1005    }
1006
1007    fn stride(&self) -> usize {
1008        self.stride
1009    }
1010
1011    fn pix(&self) -> &Vec<u8> {
1012        &self.pix
1013    }
1014
1015    fn get_pix_mutable(&mut self) -> &mut Vec<u8> {
1016        &mut self.pix
1017    }
1018
1019    fn at(&self, x: isize, y: isize) -> color::Color {
1020        color::Color::Gray(self.gray_at(x, y))
1021    }
1022
1023    fn set(&mut self, x: isize, y: isize, c: &color::Color) {
1024        if let color::Color::Gray(c) = c {
1025            self.set_gray(x, y, c);
1026        } else {
1027            self.set_gray(x, y, &color::Gray::new_from(c));
1028        };
1029    }
1030
1031    fn bytes_per_pixel(&self) -> usize {
1032        1
1033    }
1034}
1035
1036impl Gray {
1037    /// new returns a new Gray image with the given bounds.
1038    pub fn new(r: &Rectangle) -> Self {
1039        Self {
1040            pix: vec![0; pixel_buffer_length(1, r, "Gray")],
1041            stride: r.dx(),
1042            rect: *r,
1043        }
1044    }
1045
1046    // fn (p *Gray) RGBA64At(x: isize, y: isize) color::RGBA64 {
1047    // 	gray := uint16(self.GrayAt(x, y).y)
1048    // 	gray |= gray << 8
1049    // 	return color::RGBA64{gray, gray, gray, 0xffff}
1050    // }
1051
1052    pub fn gray_at(&self, x: isize, y: isize) -> color::Gray {
1053        if !(Point::new(x, y).inside(&self.rect)) {
1054            return color::Gray::new(0);
1055        }
1056        let i = self.pix_offset(x, y);
1057        color::Gray::new(self.pix[i])
1058    }
1059
1060    // pix_offset returns the index of the first element of pix that corresponds to
1061    // the pixel at (x, y).
1062    pub fn pix_offset(&self, x: isize, y: isize) -> usize {
1063        (y - self.rect.min.y) as usize * self.stride + (x - self.rect.min.x) as usize
1064    }
1065
1066    fn set_gray(&mut self, x: isize, y: isize, c: &color::Gray) {
1067        if !(Point::new(x, y).inside(&self.rect)) {
1068            return;
1069        }
1070        let i = self.pix_offset(x, y);
1071        self.pix[i] = c.y;
1072    }
1073
1074    // fn (p *Gray) SetRGBA64(x: isize, y: isize, c color::RGBA64) {
1075    // 	if !Point::new(x, y).inside(&self.rect) {
1076    // 		return
1077    // 	}
1078    // 	// This formula is the same as in color::grayModel.
1079    // 	gray := (19595*uint32(c.r) + 38470*uint32(c.g) + 7471*uint32(c.b) + 1<<15) >> 24
1080    // 	let i = self.pix_offset(x, y);
1081    // 	self.pix[i] = u8(gray)
1082    // }
1083
1084    // // SubImage returns an image representing the portion of the image p visible
1085    // // through r. The returned value shares pixels with the original image.
1086    // fn (p *Gray) SubImage(r Rectangle) Image {
1087    // 	r = r.intersect(self.rect)
1088    // 	// If r1 and r2 are Rectangles, r1.intersect(r2) is not guaranteed to be inside
1089    // 	// either r1 or r2 if the intersection is empty. Without explicitly checking for
1090    // 	// this, the pix[i:] expression below can panic.
1091    // 	if r.Empty() {
1092    // 		return &Gray{}
1093    // 	}
1094    // 	let i = self.pix_offset(r.min.x, r.min.y)
1095    // 	return &Gray{
1096    // 		pix:    self.pix[i:],
1097    // 		stride: self.stride,
1098    // 		Rect:   r,
1099    // 	}
1100    // }
1101}
1102
1103/// Gray16 is an in-memory image whose At method returns color::Gray16 values.
1104#[derive(Debug)]
1105pub struct Gray16 {
1106    /// pix holds the image's pixels, as gray values in big-endian format. The pixel at
1107    /// (x, y) starts at pix[(y-Rect.min.y)*stride + (x-Rect.min.x)*2].
1108    pub pix: Vec<u8>,
1109    /// stride is the pix stride (in bytes) between vertically adjacent pixels.
1110    pub stride: usize,
1111    /// rect is the image's bounds.
1112    rect: Rectangle,
1113}
1114
1115impl Image for Gray16 {
1116    fn color_model(&self) -> color::Model {
1117        color::Model::Gray16Model
1118    }
1119
1120    fn bounds(&self) -> &Rectangle {
1121        &self.rect
1122    }
1123
1124    /// opaque scans the entire image and reports whether it is fully opaque.
1125    fn opaque(&self) -> bool {
1126        true
1127    }
1128
1129    fn stride(&self) -> usize {
1130        self.stride
1131    }
1132
1133    fn pix(&self) -> &Vec<u8> {
1134        &self.pix
1135    }
1136
1137    fn get_pix_mutable(&mut self) -> &mut Vec<u8> {
1138        &mut self.pix
1139    }
1140
1141    fn at(&self, x: isize, y: isize) -> color::Color {
1142        color::Color::Gray16(self.gray16_at(x, y))
1143    }
1144
1145    fn set(&mut self, x: isize, y: isize, c: &color::Color) {
1146        if let color::Color::Gray16(c) = c {
1147            self.set_gray16(x, y, c);
1148        } else {
1149            self.set_gray16(x, y, &color::Gray16::new_from(c));
1150        };
1151    }
1152
1153    fn bytes_per_pixel(&self) -> usize {
1154        2
1155    }
1156}
1157
1158impl Gray16 {
1159    /// new returns a new Gray16 image with the given bounds.
1160    pub fn new(r: &Rectangle) -> Self {
1161        Self {
1162            pix: vec![0; pixel_buffer_length(2, r, "Gray16")],
1163            stride: 2 * r.dx(),
1164            rect: *r,
1165        }
1166    }
1167
1168    pub fn gray16_at(&self, x: isize, y: isize) -> color::Gray16 {
1169        if !(Point::new(x, y).inside(&self.rect)) {
1170            return color::Gray16::new(0);
1171        }
1172        let i = self.pix_offset(x, y);
1173        color::Gray16::new(((self.pix[i] as u16) << 8) | (self.pix[i + 1] as u16))
1174    }
1175
1176    // pix_offset returns the index of the first element of pix that corresponds to
1177    // the pixel at (x, y).
1178    pub fn pix_offset(&self, x: isize, y: isize) -> usize {
1179        (y - self.rect.min.y) as usize * self.stride + (x - self.rect.min.x) as usize * 2
1180    }
1181
1182    fn set_gray16(&mut self, x: isize, y: isize, c: &color::Gray16) {
1183        if !(Point::new(x, y).inside(&self.rect)) {
1184            return;
1185        }
1186        let i = self.pix_offset(x, y);
1187        self.pix[i] = (c.y >> 8) as u8;
1188        self.pix[i + 1] = (c.y) as u8;
1189    }
1190
1191    // fn (p *Gray16) color_model() color::Model { return color::Gray16Model }
1192
1193    // fn (p *Gray16) bounds() Rectangle { return self.rect }
1194
1195    // fn (p *Gray16) At(x: isize, y: isize) color::Color {
1196    // 	return self.Gray16At(x, y)
1197    // }
1198
1199    // fn (p *Gray16) RGBA64At(x: isize, y: isize) color::RGBA64 {
1200    // 	gray := self.Gray16At(x, y).y
1201    // 	return color::RGBA64{gray, gray, gray, 0xffff}
1202    // }
1203
1204    // // pix_offset returns the index of the first element of pix that corresponds to
1205    // // the pixel at (x, y).
1206    // fn (p *Gray16) pix_offset(x: isize, y: isize) isize {
1207    // 	return (y-self.rect.min.y)*self.stride + (x-self.rect.min.x)*2
1208    // }
1209
1210    // fn (p *Gray16) SetRGBA64(x: isize, y: isize, c color::RGBA64) {
1211    // 	if !Point::new(x, y).inside(&self.rect) {
1212    // 		return
1213    // 	}
1214    // 	// This formula is the same as in color::gray16Model.
1215    // 	gray := (19595*uint32(c.r) + 38470*uint32(c.g) + 7471*uint32(c.b) + 1<<15) >> 16
1216    // 	let i = self.pix_offset(x, y);
1217    // 	self.pix[i+0] = u8(gray >> 8)
1218    // 	self.pix[i+1] = u8(gray)
1219    // }
1220
1221    // fn (p *Gray16) SetGray16(x: isize, y: isize, c color::Gray16) {
1222    // 	if !Point::new(x, y).inside(&self.rect) {
1223    // 		return
1224    // 	}
1225    // 	let i = self.pix_offset(x, y);
1226    // 	self.pix[i+0] = u8(c.y >> 8)
1227    // 	self.pix[i+1] = u8(c.y)
1228    // }
1229
1230    // // SubImage returns an image representing the portion of the image p visible
1231    // // through r. The returned value shares pixels with the original image.
1232    // fn (p *Gray16) SubImage(r Rectangle) Image {
1233    // 	r = r.intersect(self.rect)
1234    // 	// If r1 and r2 are Rectangles, r1.intersect(r2) is not guaranteed to be inside
1235    // 	// either r1 or r2 if the intersection is empty. Without explicitly checking for
1236    // 	// this, the pix[i:] expression below can panic.
1237    // 	if r.Empty() {
1238    // 		return &Gray16{}
1239    // 	}
1240    // 	let i = self.pix_offset(r.min.x, r.min.y)
1241    // 	return &Gray16{
1242    // 		pix:    self.pix[i:],
1243    // 		stride: self.stride,
1244    // 		Rect:   r,
1245    // 	}
1246    // }
1247
1248    // // opaque scans the entire image and reports whether it is fully opaque.
1249    // fn (p *Gray16) opaque() bool {
1250    // 	return true
1251    // }
1252}
1253
1254// // CMYK is an in-memory image whose At method returns color::CMYK values.
1255// type CMYK struct {
1256// 	// pix holds the image's pixels, in C, M, Y, K order. The pixel at
1257// 	// (x, y) starts at pix[(y-Rect.min.y)*stride + (x-Rect.min.x)*4].
1258// 	pix [u8]
1259// 	// stride is the pix stride (in bytes) between vertically adjacent pixels.
1260// 	stride isize
1261// 	// Rect is the image's bounds.
1262// 	Rect Rectangle
1263// }
1264
1265// fn (p *CMYK) color_model() color::Model { return color::CMYKModel }
1266
1267// fn (p *CMYK) bounds() Rectangle { return self.rect }
1268
1269// fn (p *CMYK) At(x: isize, y: isize) color::Color {
1270// 	return self.CMYKAt(x, y)
1271// }
1272
1273// fn (p *CMYK) RGBA64At(x: isize, y: isize) color::RGBA64 {
1274// 	r, g, b, a := self.CMYKAt(x, y).rgba()
1275// 	return color::RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
1276// }
1277
1278// fn (p *CMYK) CMYKAt(x: isize, y: isize) color::CMYK {
1279// 	if !Point::new(x, y).inside(&self.rect) {
1280// 		return color::CMYK{}
1281// 	}
1282// 	let i = self.pix_offset(x, y);
1283// 	s := self.pix[i..i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
1284// 	return color::CMYK{s[0], s[1], s[2], s[3]}
1285// }
1286
1287// // pix_offset returns the index of the first element of pix that corresponds to
1288// // the pixel at (x, y).
1289// fn (p *CMYK) pix_offset(x: isize, y: isize) isize {
1290// 	return (y-self.rect.min.y)*self.stride + (x-self.rect.min.x)*4
1291// }
1292
1293// fn (p *CMYK) Set(x: isize, y: isize, c color::Color) {
1294// 	if !Point::new(x, y).inside(&self.rect) {
1295// 		return
1296// 	}
1297// 	let i = self.pix_offset(x, y);
1298// 	c1 := color::CMYKModel.Convert(c).(color::CMYK)
1299// 	s := self.pix[i..i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
1300// 	s[0] = c1.C
1301// 	s[1] = c1.M
1302// 	s[2] = c1.y
1303// 	s[3] = c1.K
1304// }
1305
1306// fn (p *CMYK) SetRGBA64(x: isize, y: isize, c color::RGBA64) {
1307// 	if !Point::new(x, y).inside(&self.rect) {
1308// 		return
1309// 	}
1310// 	cc, mm, yy, kk := color::RGBToCMYK(u8(c.r>>8), u8(c.g>>8), u8(c.b>>8))
1311// 	let i = self.pix_offset(x, y);
1312// 	s := self.pix[i..i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
1313// 	s[0] = cc
1314// 	s[1] = mm
1315// 	s[2] = yy
1316// 	s[3] = kk
1317// }
1318
1319// fn (p *CMYK) SetCMYK(x: isize, y: isize, c color::CMYK) {
1320// 	if !Point::new(x, y).inside(&self.rect) {
1321// 		return
1322// 	}
1323// 	let i = self.pix_offset(x, y);
1324// 	s := self.pix[i..i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
1325// 	s[0] = c.C
1326// 	s[1] = c.M
1327// 	s[2] = c.y
1328// 	s[3] = c.K
1329// }
1330
1331// // SubImage returns an image representing the portion of the image p visible
1332// // through r. The returned value shares pixels with the original image.
1333// fn (p *CMYK) SubImage(r Rectangle) Image {
1334// 	r = r.intersect(self.rect)
1335// 	// If r1 and r2 are Rectangles, r1.intersect(r2) is not guaranteed to be inside
1336// 	// either r1 or r2 if the intersection is empty. Without explicitly checking for
1337// 	// this, the pix[i:] expression below can panic.
1338// 	if r.Empty() {
1339// 		return &CMYK{}
1340// 	}
1341// 	let i = self.pix_offset(r.min.x, r.min.y)
1342// 	return &CMYK{
1343// 		pix:    self.pix[i:],
1344// 		stride: self.stride,
1345// 		Rect:   r,
1346// 	}
1347// }
1348
1349// // opaque scans the entire image and reports whether it is fully opaque.
1350// fn (p *CMYK) opaque() bool {
1351// 	return true
1352// }
1353
1354// // NewCMYK returns a new CMYK image with the given bounds.
1355// fn NewCMYK(r Rectangle) *CMYK {
1356// 	return &CMYK{
1357// 		pix:    make([u8], pixel_buffer_length(4, r, "CMYK")),
1358// 		stride: 4 * r.dx(),
1359// 		Rect:   r,
1360// 	}
1361// }
1362
1363/// Paletted is an in-memory image of u8 indices into a given palette.
1364#[derive(Debug)]
1365pub struct Paletted {
1366    /// pix holds the image's pixels, as palette indices. The pixel at
1367    /// (x, y) starts at pix[(y-Rect.min.y)*stride + (x-Rect.min.x)*1].
1368    pub pix: Vec<u8>,
1369    /// stride is the pix stride (in bytes) between vertically adjacent pixels.
1370    pub stride: usize,
1371    /// rect is the image's bounds.
1372    rect: Rectangle,
1373    /// palette is the image's palette.
1374    pub(super) palette: color::Palette,
1375}
1376
1377impl Image for Paletted {
1378    fn color_model(&self) -> color::Model {
1379        color::Model::Paletted(self.palette.clone())
1380    }
1381
1382    fn bounds(&self) -> &Rectangle {
1383        &self.rect
1384    }
1385
1386    fn at(&self, x: isize, y: isize) -> color::Color {
1387        if self.palette.colors.is_empty() {
1388            return color::Color::new_rgba(0, 0, 0, 0);
1389        }
1390        if !(Point::new(x, y).inside(&self.rect)) {
1391            return self.palette.colors[0];
1392        }
1393        let i = self.pix_offset(x, y);
1394        self.palette.colors[self.pix[i] as usize]
1395    }
1396
1397    fn set(&mut self, x: isize, y: isize, c: &color::Color) {
1398        if !(Point::new(x, y).inside(&self.rect)) {
1399            return;
1400        }
1401        let i = self.pix_offset(x, y);
1402        self.pix[i] = self.palette.index(c) as u8;
1403    }
1404
1405    // opaque scans the entire image and reports whether it is fully opaque.
1406    fn opaque(&self) -> bool {
1407        let mut present = [false; 256];
1408        let (mut i0, mut i1) = (0, self.rect.dx());
1409        for _y in self.rect.min.y..self.rect.max.y {
1410            for c in &self.pix[i0..i1] {
1411                present[*c as usize] = true;
1412            }
1413            i0 += self.stride;
1414            i1 += self.stride;
1415        }
1416        for (i, c) in self.palette.colors.iter().enumerate() {
1417            if !present[i] {
1418                continue;
1419            }
1420            let (_, _, _, a) = c.rgba();
1421            if a != 0xffff {
1422                return false;
1423            }
1424        }
1425        true
1426    }
1427
1428    fn stride(&self) -> usize {
1429        self.stride
1430    }
1431
1432    fn pix(&self) -> &Vec<u8> {
1433        &self.pix
1434    }
1435
1436    fn get_pix_mutable(&mut self) -> &mut Vec<u8> {
1437        &mut self.pix
1438    }
1439
1440    fn bytes_per_pixel(&self) -> usize {
1441        1
1442    }
1443}
1444
1445impl Paletted {
1446    /// new returns a new Paletted image with the given width, height and
1447    /// palette.
1448    pub fn new(r: &Rectangle, p: color::Palette) -> Self {
1449        Self {
1450            pix: vec![0; pixel_buffer_length(1, r, "Paletted")],
1451            stride: r.dx(),
1452            rect: *r,
1453            palette: p,
1454        }
1455    }
1456
1457    // fn RGBA64At(&self, x: isize, y: isize) color::RGBA64 {
1458    // 	if self.palette.colors.len() == 0 {
1459    // 		return color::RGBA64{}
1460    // 	}
1461    // 	c := color::Color(nil)
1462    // 	if !Point::new(x, y).inside(&self.rect) {
1463    // 		c = self.palette.colors[0]
1464    // 	} else {
1465    // 		i := self.pix_offset(x, y)
1466    // 		c = self.palette.colors[self.pix[i]]
1467    // 	}
1468    // 	r, g, b, a := c.rgba()
1469    // 	return color::RGBA64{
1470    // 		uint16(r),
1471    // 		uint16(g),
1472    // 		uint16(b),
1473    // 		uint16(a),
1474    // 	}
1475    // }
1476
1477    /// pix_offset returns the index of the first element of pix that corresponds to
1478    /// the pixel at (x, y).
1479    pub fn pix_offset(&self, x: isize, y: isize) -> usize {
1480        (y - self.rect.min.y) as usize * self.stride + (x - self.rect.min.x) as usize
1481    }
1482
1483    // fn SetRGBA64(&self, x: isize, y: isize, c color::RGBA64) {
1484    // 	if !Point::new(x, y).inside(&self.rect) {
1485    // 		return
1486    // 	}
1487    // 	let i = self.pix_offset(x, y);
1488    // 	self.pix[i] = u8(self.palette.Index(c))
1489    // }
1490
1491    pub fn color_index_at(&self, x: isize, y: isize) -> u8 {
1492        if !(Point::new(x, y).inside(&self.rect)) {
1493            return 0;
1494        }
1495        let i = self.pix_offset(x, y);
1496        self.pix[i]
1497    }
1498
1499    pub fn set_color_index(&mut self, x: isize, y: isize, index: u8) {
1500        if !Point::new(x, y).inside(&self.rect) {
1501            return;
1502        }
1503        let i = self.pix_offset(x, y);
1504        self.pix[i] = index;
1505    }
1506
1507    // // SubImage returns an image representing the portion of the image p visible
1508    // // through r. The returned value shares pixels with the original image.
1509    // fn SubImage(&self, r Rectangle) Image {
1510    // 	r = r.intersect(self.rect)
1511    // 	// If r1 and r2 are Rectangles, r1.intersect(r2) is not guaranteed to be inside
1512    // 	// either r1 or r2 if the intersection is empty. Without explicitly checking for
1513    // 	// this, the pix[i:] expression below can panic.
1514    // 	if r.Empty() {
1515    // 		return &Paletted{
1516    // 			Palette: self.palette,
1517    // 		}
1518    // 	}
1519    // 	let i = self.pix_offset(r.min.x, r.min.y)
1520    // 	return &Paletted{
1521    // 		pix:     self.pix[i:],
1522    // 		stride:  self.stride,
1523    // 		Rect:    self.rect.intersect(r),
1524    // 		Palette: self.palette,
1525    // 	}
1526    // }
1527}
1528
1529/// Img is a combination of all possible image types.
1530#[derive(Debug)]
1531pub enum Img {
1532    Alpha(Alpha),
1533    Alpha16(Alpha16),
1534    Gray(Gray),
1535    Gray16(Gray16),
1536    NRGBA(NRGBA),
1537    NRGBA64(NRGBA64),
1538    Paletted(Paletted),
1539    RGBA(RGBA),
1540    RGBA64(RGBA64),
1541}
1542
1543impl Img {
1544    /// new_rgba creates a new RGBA image.
1545    pub fn new_rgba(r: &Rectangle) -> Self {
1546        Self::RGBA(RGBA::new(r))
1547    }
1548    /// new_nrgba creates a new NRGBA image.
1549    pub fn new_nrgba(r: &Rectangle) -> Self {
1550        Self::NRGBA(NRGBA::new(r))
1551    }
1552    /// new_nrgba64 creates a new NRGBA64 image.
1553    pub fn new_nrgba64(r: &Rectangle) -> Img {
1554        Img::NRGBA64(NRGBA64::new(r))
1555    }
1556    /// new_rgba64 creates a new RGBA64 image.
1557    pub fn new_rgba64(r: &Rectangle) -> Img {
1558        Img::RGBA64(RGBA64::new(r))
1559    }
1560}
1561
1562impl Image for Img {
1563    fn bytes_per_pixel(&self) -> usize {
1564        match self {
1565            Img::Paletted(img) => img.bytes_per_pixel(),
1566            Img::RGBA(img) => img.bytes_per_pixel(),
1567            Img::NRGBA(img) => img.bytes_per_pixel(),
1568            Img::RGBA64(img) => img.bytes_per_pixel(),
1569            Img::NRGBA64(img) => img.bytes_per_pixel(),
1570            Img::Alpha(img) => img.bytes_per_pixel(),
1571            Img::Alpha16(img) => img.bytes_per_pixel(),
1572            Img::Gray(img) => img.bytes_per_pixel(),
1573            Img::Gray16(img) => img.bytes_per_pixel(),
1574        }
1575    }
1576    fn stride(&self) -> usize {
1577        match self {
1578            Img::Paletted(img) => img.stride(),
1579            Img::RGBA(img) => img.stride(),
1580            Img::NRGBA(img) => img.stride(),
1581            Img::RGBA64(img) => img.stride(),
1582            Img::NRGBA64(img) => img.stride(),
1583            Img::Alpha(img) => img.stride(),
1584            Img::Alpha16(img) => img.stride(),
1585            Img::Gray(img) => img.stride(),
1586            Img::Gray16(img) => img.stride(),
1587        }
1588    }
1589    fn bounds(&self) -> &Rectangle {
1590        match self {
1591            Img::Paletted(img) => img.bounds(),
1592            Img::RGBA(img) => img.bounds(),
1593            Img::NRGBA(img) => img.bounds(),
1594            Img::RGBA64(img) => img.bounds(),
1595            Img::NRGBA64(img) => img.bounds(),
1596            Img::Alpha(img) => img.bounds(),
1597            Img::Alpha16(img) => img.bounds(),
1598            Img::Gray(img) => img.bounds(),
1599            Img::Gray16(img) => img.bounds(),
1600        }
1601    }
1602    fn pix(&self) -> &Vec<u8> {
1603        match self {
1604            Img::Paletted(img) => img.pix(),
1605            Img::RGBA(img) => img.pix(),
1606            Img::NRGBA(img) => img.pix(),
1607            Img::RGBA64(img) => img.pix(),
1608            Img::NRGBA64(img) => img.pix(),
1609            Img::Alpha(img) => img.pix(),
1610            Img::Alpha16(img) => img.pix(),
1611            Img::Gray(img) => img.pix(),
1612            Img::Gray16(img) => img.pix(),
1613        }
1614    }
1615    fn get_pix_mutable(&mut self) -> &mut Vec<u8> {
1616        match self {
1617            Img::Paletted(img) => img.get_pix_mutable(),
1618            Img::RGBA(img) => img.get_pix_mutable(),
1619            Img::NRGBA(img) => img.get_pix_mutable(),
1620            Img::RGBA64(img) => img.get_pix_mutable(),
1621            Img::NRGBA64(img) => img.get_pix_mutable(),
1622            Img::Alpha(img) => img.get_pix_mutable(),
1623            Img::Alpha16(img) => img.get_pix_mutable(),
1624            Img::Gray(img) => img.get_pix_mutable(),
1625            Img::Gray16(img) => img.get_pix_mutable(),
1626        }
1627    }
1628
1629    fn color_model(&self) -> color::Model {
1630        match self {
1631            Img::Paletted(img) => img.color_model(),
1632            Img::RGBA(img) => img.color_model(),
1633            Img::NRGBA(img) => img.color_model(),
1634            Img::RGBA64(img) => img.color_model(),
1635            Img::NRGBA64(img) => img.color_model(),
1636            Img::Alpha(img) => img.color_model(),
1637            Img::Alpha16(img) => img.color_model(),
1638            Img::Gray(img) => img.color_model(),
1639            Img::Gray16(img) => img.color_model(),
1640        }
1641    }
1642
1643    fn at(&self, x: isize, y: isize) -> color::Color {
1644        match self {
1645            Img::Paletted(img) => img.at(x, y),
1646            Img::RGBA(img) => img.at(x, y),
1647            Img::NRGBA(img) => img.at(x, y),
1648            Img::RGBA64(img) => img.at(x, y),
1649            Img::NRGBA64(img) => img.at(x, y),
1650            Img::Alpha(img) => img.at(x, y),
1651            Img::Alpha16(img) => img.at(x, y),
1652            Img::Gray(img) => img.at(x, y),
1653            Img::Gray16(img) => img.at(x, y),
1654        }
1655    }
1656
1657    fn set(&mut self, x: isize, y: isize, c: &color::Color) {
1658        match self {
1659            Img::Paletted(img) => img.set(x, y, c),
1660            Img::RGBA(img) => img.set(x, y, c),
1661            Img::NRGBA(img) => img.set(x, y, c),
1662            Img::RGBA64(img) => img.set(x, y, c),
1663            Img::NRGBA64(img) => img.set(x, y, c),
1664            Img::Alpha(img) => img.set(x, y, c),
1665            Img::Alpha16(img) => img.set(x, y, c),
1666            Img::Gray(img) => img.set(x, y, c),
1667            Img::Gray16(img) => img.set(x, y, c),
1668        }
1669    }
1670
1671    fn opaque(&self) -> bool {
1672        match self {
1673            Img::Paletted(img) => img.opaque(),
1674            Img::RGBA(img) => img.opaque(),
1675            Img::NRGBA(img) => img.opaque(),
1676            Img::RGBA64(img) => img.opaque(),
1677            Img::NRGBA64(img) => img.opaque(),
1678            Img::Alpha(img) => img.opaque(),
1679            Img::Alpha16(img) => img.opaque(),
1680            Img::Gray(img) => img.opaque(),
1681            Img::Gray16(img) => img.opaque(),
1682        }
1683    }
1684}