1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright (c) 2015-2017 The `img_hash` Crate Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use image::{
    imageops,
    DynamicImage,
    FilterType,
    GrayImage,
    GrayAlphaImage,
    RgbImage,
    RgbaImage,
    GenericImage,
    Pixel
};

use super::HashImage;

const FILTER_TYPE: FilterType = FilterType::Nearest;

macro_rules! hash_img_impl {
    ($ty:ident ($lumaty:ty)) => (
        impl HashImage for $ty {
            type Grayscale = $lumaty;

            fn dimensions(&self) -> (u32, u32) {
                self.dimensions()
            }

            fn resize(&self, width: u32, height: u32) -> Self {
                imageops::resize(self, width, height, FILTER_TYPE)
            }

            fn grayscale(&self) -> $lumaty {
                imageops::grayscale(self)
            }

            fn to_bytes(self) -> Vec<u8> {
                self.into_raw()
            }

            fn channel_count() -> u8 {
                <<Self as GenericImage>::Pixel as Pixel>::channel_count()
            }

            fn foreach_pixel<F>(&self, mut iter_fn: F) where F: FnMut(u32, u32, &[u8]) {
                for (x, y, px) in self.enumerate_pixels() {
                    iter_fn(x, y, px.channels());
                }
            }
        }
    );
    ($($ty:ident ($lumaty:ty)),+) => ( $(hash_img_impl! { $ty($lumaty) })+ );
}

hash_img_impl! { 
    GrayImage(GrayImage), GrayAlphaImage(GrayImage), 
    RgbImage(GrayImage), RgbaImage(GrayImage) 
}

impl HashImage for DynamicImage {
            type Grayscale = GrayImage;

            fn dimensions(&self) -> (u32, u32) {
                <Self as GenericImage>::dimensions(self) 
            }

            fn resize(&self, width: u32, height: u32) -> Self {
                self.resize(width, height, FILTER_TYPE)
            }

            fn grayscale(&self) -> GrayImage {
                imageops::grayscale(self)
            }

            fn to_bytes(self) -> Vec<u8> {
                self.raw_pixels()
            }

            fn channel_count() -> u8 {
                <<Self as GenericImage>::Pixel as Pixel>::channel_count()
            }

            fn foreach_pixel<F>(&self, mut iter_fn: F) where F: FnMut(u32, u32, &[u8]) {
                for (x, y, px) in self.pixels() {
                    iter_fn(x, y, px.channels());
                }
            }
        }