summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/image_saver/save_png.h
blob: cddf03ff61c8659db301294d95b334ef4aa20a98 (plain)
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// Copyright (C) 2011  Davis E. King (davis@dlib.net)
// License: Boost Software License   See LICENSE.txt for the full license.
#ifndef DLIB_SAVE_PnG_Hh_
#define DLIB_SAVE_PnG_Hh_

#include "save_png_abstract.h"
#include "image_saver.h"
#include "../array2d.h"
#include <vector>
#include <string>
#include "../pixel.h"
#include "../matrix/matrix_exp.h"
#include "../image_transforms/assign_image.h"

namespace dlib
{

// ----------------------------------------------------------------------------------------

    namespace impl
    {
        enum png_type
        {
            png_type_rgb,
            png_type_rgb_alpha,
            png_type_gray,
        };

        void impl_save_png (
            const std::string& file_name,
            std::vector<unsigned char*>& row_pointers,
            const long width,
            const png_type type,
            const int bit_depth
        );
    }

// ----------------------------------------------------------------------------------------

    template <
        typename image_type
        >
    typename disable_if<is_matrix<image_type> >::type save_png(
        const image_type& img_,
        const std::string& file_name
    )
    {
        const_image_view<image_type> img(img_);

        // make sure requires clause is not broken
        DLIB_CASSERT(img.size() != 0,
            "\t save_png()"
            << "\n\t You can't save an empty image as a PNG"
            );


#ifndef DLIB_PNG_SUPPORT
            /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                You are getting this error because you are trying to use save_png() 
                but you haven't defined DLIB_PNG_SUPPORT.  You must do so to use
                this function.   You must also make sure you set your build environment
                to link against the libpng library.
            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
            COMPILE_TIME_ASSERT(sizeof(image_type) == 0);
#else
        std::vector<unsigned char*> row_pointers(img.nr());
        typedef typename image_traits<image_type>::pixel_type pixel_type;

        if (is_same_type<rgb_pixel,pixel_type>::value)
        {
            for (unsigned long i = 0; i < row_pointers.size(); ++i)
                row_pointers[i] = (unsigned char*)(&img[i][0]);

            impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_rgb, 8);
        }
        else if (is_same_type<rgb_alpha_pixel,pixel_type>::value)
        {
            for (unsigned long i = 0; i < row_pointers.size(); ++i)
                row_pointers[i] = (unsigned char*)(&img[i][0]);

            impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_rgb_alpha, 8);
        }
        else if (pixel_traits<pixel_type>::lab || pixel_traits<pixel_type>::hsi || pixel_traits<pixel_type>::rgb)
        {
            // convert from Lab or HSI to RGB (Or potentially RGB pixels that aren't laid out as R G B)
            array2d<rgb_pixel> temp_img;
            assign_image(temp_img, img_);
            for (unsigned long i = 0; i < row_pointers.size(); ++i)
                row_pointers[i] = (unsigned char*)(&temp_img[i][0]);

            impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_rgb, 8);
        }
        else if (pixel_traits<pixel_type>::rgb_alpha)
        {
            // convert from RGBA pixels that aren't laid out as R G B A
            array2d<rgb_alpha_pixel> temp_img;
            assign_image(temp_img, img_);
            for (unsigned long i = 0; i < row_pointers.size(); ++i)
                row_pointers[i] = (unsigned char*)(&temp_img[i][0]);

            impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_rgb_alpha, 8);
        }
        else // this is supposed to be grayscale 
        {
            DLIB_CASSERT(pixel_traits<pixel_type>::grayscale, "impossible condition detected");

            if (pixel_traits<pixel_type>::is_unsigned && sizeof(pixel_type) == 1)
            {
                for (unsigned long i = 0; i < row_pointers.size(); ++i)
                    row_pointers[i] = (unsigned char*)(&img[i][0]);

                impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_gray, 8);
            }
            else if (pixel_traits<pixel_type>::is_unsigned && sizeof(pixel_type) == 2)
            {
                for (unsigned long i = 0; i < row_pointers.size(); ++i)
                    row_pointers[i] = (unsigned char*)(&img[i][0]);

                impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_gray, 16);
            }
            else
            {
                // convert from whatever this is to 16bit grayscale 
                array2d<dlib::uint16> temp_img;
                assign_image(temp_img, img_);
                for (unsigned long i = 0; i < row_pointers.size(); ++i)
                    row_pointers[i] = (unsigned char*)(&temp_img[i][0]);

                impl::impl_save_png(file_name, row_pointers, img.nc(), impl::png_type_gray, 16);
            }
        }


#endif

    }

// ----------------------------------------------------------------------------------------

    template <
        typename EXP 
        >
    void save_png(
        const matrix_exp<EXP>& img,
        const std::string& file_name
    )
    {
        array2d<typename EXP::type> temp;
        assign_image(temp, img);
        save_png(temp, file_name);
    }

// ----------------------------------------------------------------------------------------

}

#ifdef NO_MAKEFILE
#include "save_png.cpp"
#endif

#endif // DLIB_SAVE_PnG_Hh_