Line | Branch | Exec | Source |
---|---|---|---|
1 | /*************************************** | ||
2 | Auteur : Pierre Aubert | ||
3 | Mail : pierre.aubert@lapp.in2p3.fr | ||
4 | Licence : CeCILL-C | ||
5 | ****************************************/ | ||
6 | |||
7 | #include <string.h> | ||
8 | |||
9 | #include "PImagePng.h" | ||
10 | |||
11 | ///Default constructor of PImagePng | ||
12 | 18 | PImagePng::PImagePng(){ | |
13 | 18 | initialisationPImagePng(); | |
14 | 18 | } | |
15 | |||
16 | ///Copy constructor of PImagePng | ||
17 | /** @param other : class to copy | ||
18 | */ | ||
19 | 1 | PImagePng::PImagePng(const PImagePng & other){ | |
20 | 1 | initialisationPImagePng(); | |
21 | 1 | copyPImagePng(other); | |
22 | 1 | } | |
23 | |||
24 | ///Destructor of PImagePng | ||
25 | 19 | PImagePng::~PImagePng(){ | |
26 | 19 | clear(); | |
27 | 19 | } | |
28 | |||
29 | ///Definition of equal operator of PImagePng | ||
30 | /** @param other : class to copy | ||
31 | * @return copied class | ||
32 | */ | ||
33 | 1 | PImagePng & PImagePng::operator = (const PImagePng & other){ | |
34 | 1 | copyPImagePng(other); | |
35 | 1 | return *this; | |
36 | } | ||
37 | |||
38 | ///Create an image | ||
39 | /** @param width : width of the image | ||
40 | * @param height : height of the image | ||
41 | * @param colorType : color type of the image (ex RGB) | ||
42 | * @return true on success, false otherwise | ||
43 | */ | ||
44 | 18 | bool PImagePng::createImage(size_t width, size_t height, PImagePng::ColorType colorType){ | |
45 | 18 | p_image.width = width; | |
46 | 18 | p_image.height = height; | |
47 | 18 | p_colorType = colorType; | |
48 |
2/2✓ Branch 0 (2→3) taken 13 times.
✓ Branch 1 (2→4) taken 5 times.
|
18 | if(colorType == PImagePng::RGB){ |
49 | 13 | p_image.format = PNG_FORMAT_RGB; | |
50 | 13 | p_nbBytePerPixel = 3; | |
51 |
1/2✓ Branch 0 (4→5) taken 5 times.
✗ Branch 1 (4→6) not taken.
|
5 | }else if(colorType == PImagePng::RGBA){ |
52 | 5 | p_image.format = PNG_FORMAT_RGBA; | |
53 | 5 | p_nbBytePerPixel = 4; | |
54 | } | ||
55 |
2/2✓ Branch 0 (6→7) taken 1 times.
✓ Branch 1 (6→8) taken 17 times.
|
18 | if(p_buffer != NULL){ |
56 | 1 | free(p_buffer); | |
57 | } | ||
58 |
2/4✓ Branch 0 (8→9) taken 18 times.
✗ Branch 1 (8→10) not taken.
✓ Branch 2 (11→12) taken 18 times.
✗ Branch 3 (11→13) not taken.
|
18 | p_buffer = (png_byte*)malloc(PNG_IMAGE_SIZE(p_image)); |
59 | |||
60 | // png_structp pngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); | ||
61 | // if(pngStruct == NULL){return false;} | ||
62 | // png_infop infoPtr = png_create_info_struct(pngStruct); | ||
63 | // if(infoPtr == NULL){return false;} | ||
64 | // png_set_IHDR(pngStruct, infoPtr, width, height, | ||
65 | // 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, | ||
66 | // PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); | ||
67 | 18 | return true; | |
68 | } | ||
69 | |||
70 | ///Read the given png image | ||
71 | /** @param fileName : name of the file to be read | ||
72 | * @return true on success, false otherwise | ||
73 | */ | ||
74 | 4 | bool PImagePng::read(const PPath & fileName){ | |
75 |
2/2✓ Branch 0 (3→4) taken 1 times.
✓ Branch 1 (3→5) taken 3 times.
|
4 | if(fileName == ""){return false;} |
76 |
2/2✓ Branch 0 (6→7) taken 2 times.
✓ Branch 1 (6→12) taken 1 times.
|
3 | if(!check_is_png(fileName)){ |
77 | 2 | std::cerr << "PImagePng::read : file is not a png '"<<fileName<<"'" << std::endl; | |
78 | 2 | return false; | |
79 | } | ||
80 |
1/2✗ Branch 0 (14→15) not taken.
✓ Branch 1 (14→20) taken 1 times.
|
1 | if(png_image_begin_read_from_file(&p_image, fileName.c_str()) == 0){ |
81 | ✗ | std::cerr << "PImagePng::read : cannot read png image '"<<fileName<<"'" << std::endl; | |
82 | ✗ | return false; | |
83 | } | ||
84 | /* Set the format in which to read the PNG file; this code chooses a | ||
85 | * simple sRGB format with a non-associated alpha channel, adequate to | ||
86 | * store most images. | ||
87 | */ | ||
88 |
1/2✗ Branch 0 (20→21) not taken.
✓ Branch 1 (20→22) taken 1 times.
|
1 | if(p_image.format == PNG_FORMAT_RGB){ |
89 | ✗ | p_nbBytePerPixel = 3; | |
90 | ✗ | p_colorType = PImagePng::RGB; | |
91 |
1/2✓ Branch 0 (22→23) taken 1 times.
✗ Branch 1 (22→24) not taken.
|
1 | }else if(p_image.format == PNG_FORMAT_RGBA){ |
92 | 1 | p_nbBytePerPixel = 4; | |
93 | 1 | p_colorType = PImagePng::RGBA; | |
94 | } | ||
95 | |||
96 | /* Now allocate enough memory to hold the image in this format; the | ||
97 | * PNG_IMAGE_SIZE macro uses the information about the image (width, | ||
98 | * height and format) stored in 'image'. | ||
99 | */ | ||
100 |
2/4✓ Branch 0 (24→25) taken 1 times.
✗ Branch 1 (24→26) not taken.
✓ Branch 2 (27→28) taken 1 times.
✗ Branch 3 (27→29) not taken.
|
1 | p_buffer = (png_byte*)malloc(PNG_IMAGE_SIZE(p_image)); |
101 |
2/4✓ Branch 0 (30→31) taken 1 times.
✗ Branch 1 (30→34) not taken.
✓ Branch 2 (35→36) taken 1 times.
✗ Branch 3 (35→37) not taken.
|
2 | if(p_buffer != NULL && |
102 |
1/2✓ Branch 0 (32→33) taken 1 times.
✗ Branch 1 (32→34) not taken.
|
1 | png_image_finish_read(&p_image, NULL/*background*/, p_buffer, 0/*row_stride*/, NULL/*colormap*/) != 0){ |
103 | 1 | return true; | |
104 | } | ||
105 | ✗ | return false; | |
106 | } | ||
107 | |||
108 | ///Write a png file | ||
109 | /** @param fileName : name fo the png file to be written | ||
110 | * @return true on success, false otherwise | ||
111 | */ | ||
112 | 15 | bool PImagePng::write(const PPath & fileName){ | |
113 |
3/6✓ Branch 0 (3→4) taken 15 times.
✗ Branch 1 (3→5) not taken.
✗ Branch 2 (4→5) not taken.
✓ Branch 3 (4→6) taken 15 times.
✗ Branch 4 (7→8) not taken.
✓ Branch 5 (7→9) taken 15 times.
|
15 | if(fileName == "" || p_buffer == NULL){return false;} |
114 |
1/2✓ Branch 0 (11→12) taken 15 times.
✗ Branch 1 (11→13) not taken.
|
15 | if(png_image_write_to_file(&p_image, fileName.c_str(), 0/*convert_to_8bit*/, p_buffer, 0/*row_stride*/, NULL/*colormap*/) != 0){ |
115 | /* The image has been written successfully. */ | ||
116 | 15 | return true; | |
117 | } | ||
118 | ✗ | return false; | |
119 | } | ||
120 | |||
121 | ///Clear the image and buffer | ||
122 | 19 | void PImagePng::clear(){ | |
123 |
2/2✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→4) taken 18 times.
|
19 | if(p_buffer == NULL){ |
124 | 1 | png_image_free(&p_image); | |
125 | }else{ | ||
126 | 18 | free(p_buffer); | |
127 | } | ||
128 | 19 | } | |
129 | |||
130 | ///Fill the image with the given color | ||
131 | /** @param red : red proportion | ||
132 | * @param green : green proportion | ||
133 | * @param blue : blue proportion | ||
134 | * @param alpha : transparence proportion | ||
135 | */ | ||
136 | 9 | void PImagePng::fill(color_t red, color_t green, color_t blue, color_t alpha){ | |
137 |
2/2✓ Branch 0 (8→3) taken 4320 times.
✓ Branch 1 (8→9) taken 9 times.
|
4329 | for(png_uint_32 j(0u); j < p_image.height; ++j){ |
138 |
2/2✓ Branch 0 (6→4) taken 2764800 times.
✓ Branch 1 (6→7) taken 4320 times.
|
2769120 | for(png_uint_32 i(0u); i < p_image.width; ++i){ |
139 | 2764800 | setColor(i, j, red, green, blue); | |
140 | } | ||
141 | } | ||
142 | 9 | } | |
143 | |||
144 | ///Set the color of the pixel at (idxWidth, idxHeight) | ||
145 | /** @param idxWidth : index of the pixel on the image width | ||
146 | * @param idxHeight : index of the pixel on the image height | ||
147 | * @param red : red proportion | ||
148 | * @param green : green proportion | ||
149 | * @param blue : blue proportion | ||
150 | */ | ||
151 | 4608000 | void PImagePng::setColor(size_t idxWidth, size_t idxHeight, color_t red, color_t green, color_t blue){ | |
152 | 4608000 | color_t alpha(255); | |
153 | 4608000 | setColor(idxWidth, idxHeight, red, green , blue, alpha); | |
154 | 4608000 | } | |
155 | |||
156 | ///Set the color of the pixel at (idxWidth, idxHeight) | ||
157 | /** @param idxWidth : index of the pixel on the image width | ||
158 | * @param idxHeight : index of the pixel on the image height | ||
159 | * @param red : red proportion | ||
160 | * @param green : green proportion | ||
161 | * @param blue : blue proportion | ||
162 | * @param alpha : alpha proportion | ||
163 | */ | ||
164 | 5529600 | void PImagePng::setColor(size_t idxWidth, size_t idxHeight, color_t red, color_t green, color_t blue, color_t alpha){ | |
165 | 5529600 | size_t index((idxHeight*p_image.width + idxWidth)*p_nbBytePerPixel); | |
166 | 5529600 | p_buffer[index] = red; | |
167 | 5529600 | p_buffer[index + 1lu] = green; | |
168 | 5529600 | p_buffer[index + 2lu] = blue; | |
169 |
2/2✓ Branch 0 (2→3) taken 1843200 times.
✓ Branch 1 (2→4) taken 3686400 times.
|
5529600 | if(p_nbBytePerPixel >= 4lu){ |
170 | 1843200 | p_buffer[index + 3lu] = alpha; | |
171 | } | ||
172 | 5529600 | } | |
173 | |||
174 | ///Get the color of the pixel at (idxWidth, idxHeight) | ||
175 | /** @param idxWidth : index of the pixel on the image width | ||
176 | * @param idxHeight : index of the pixel on the image height | ||
177 | * @param[out] red : red proportion | ||
178 | * @param[out] green : green proportion | ||
179 | * @param[out] blue : blue proportion | ||
180 | */ | ||
181 | ✗ | void PImagePng::getColor(size_t idxWidth, size_t idxHeight, color_t & red, color_t & green, color_t & blue) const{ | |
182 | ✗ | color_t alpha(255); | |
183 | ✗ | getColor(idxWidth, idxHeight, red, green , blue, alpha); | |
184 | ✗ | } | |
185 | |||
186 | ///Get the color of the pixel at (idxWidth, idxHeight) | ||
187 | /** @param idxWidth : index of the pixel on the image width | ||
188 | * @param idxHeight : index of the pixel on the image height | ||
189 | * @param[out] red : red proportion | ||
190 | * @param[out] green : green proportion | ||
191 | * @param[out] blue : blue proportion | ||
192 | * @param[out] alpha : alpha proportion | ||
193 | */ | ||
194 | 2 | void PImagePng::getColor(size_t idxWidth, size_t idxHeight, color_t & red, color_t & green, color_t & blue, color_t & alpha) const{ | |
195 | 2 | size_t index((idxHeight*p_image.width + idxWidth)*p_nbBytePerPixel); | |
196 | 2 | red = p_buffer[index]; | |
197 | 2 | green = p_buffer[index + 1lu]; | |
198 | 2 | blue = p_buffer[index + 2lu]; | |
199 |
1/2✓ Branch 0 (2→3) taken 2 times.
✗ Branch 1 (2→4) not taken.
|
2 | if(p_nbBytePerPixel >= 4lu){ |
200 | 2 | alpha = p_buffer[index + 3lu]; | |
201 | } | ||
202 | 2 | } | |
203 | |||
204 | ///Get the width of the image | ||
205 | /** @return width of the image | ||
206 | */ | ||
207 | 11 | unsigned int PImagePng::getWidth() const{return p_image.width;} | |
208 | |||
209 | ///Get the height of the image | ||
210 | /** @return height of the image | ||
211 | */ | ||
212 | 11 | unsigned int PImagePng::getHeight() const{return p_image.height;} | |
213 | |||
214 | ///Get the buffer data of the current PImagePng | ||
215 | /** @return buffer data of the current PImagePng | ||
216 | */ | ||
217 | 1 | const png_byte* PImagePng::getData() const{return p_buffer;} | |
218 | |||
219 | ///Get the buffer data of the current PImagePng | ||
220 | /** @return buffer data of the current PImagePng | ||
221 | */ | ||
222 | 1 | png_byte* PImagePng::getData(){return p_buffer;} | |
223 | |||
224 | ///Get the number of bytes per pixel | ||
225 | /** @return number of bytes per pixel | ||
226 | */ | ||
227 | 8 | NbColorByte PImagePng::getNbBytePerPixel() const{return p_nbBytePerPixel;} | |
228 | |||
229 | ///Copy function of PImagePng | ||
230 | /** @param other : class to copy | ||
231 | */ | ||
232 | 2 | void PImagePng::copyPImagePng(const PImagePng & other){ | |
233 | 2 | createImage(other.getWidth(), other.getHeight(), other.p_colorType); | |
234 | 2 | memcpy(p_buffer, other.p_buffer, sizeof(char)*other.getWidth()*other.getHeight()*p_nbBytePerPixel); | |
235 | 2 | } | |
236 | |||
237 | ///Initialisation function of the class PImagePng | ||
238 | 19 | void PImagePng::initialisationPImagePng(){ | |
239 | 19 | memset(&p_image, 0, (sizeof p_image)); | |
240 | 19 | p_image.version = PNG_IMAGE_VERSION; //We have to set the PNG version for this image | |
241 | |||
242 | 19 | p_buffer = NULL; | |
243 | 19 | p_nbBytePerPixel = 0; | |
244 | 19 | } | |
245 | |||
246 | |||
247 | |||
248 | |||
249 | |||
250 |