00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <pcl/compression/libpng_wrapper.h>
00039
00040 #include <png.h>
00041 #include <zlib.h>
00042
00043 #include <vector>
00044 #include <stdlib.h>
00045 #include <stdio.h>
00046 #include <stdint.h>
00047 #include <assert.h>
00048
00049
00050
00051 namespace
00052 {
00054 void
00055 user_read_data (png_structp png_ptr, png_bytep data, png_size_t length)
00056 {
00057 uint8_t** input_pointer = reinterpret_cast<uint8_t**>(png_get_io_ptr (png_ptr));
00058
00059 memcpy (data, *input_pointer, sizeof (uint8_t) * length);
00060 (*input_pointer) += length;
00061 }
00062
00064 void
00065 user_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
00066 {
00067 std::vector<uint8_t>* pngVec = reinterpret_cast<std::vector<uint8_t>*>(png_get_io_ptr (png_ptr));
00068 std::copy (data, data + length, std::back_inserter (*pngVec));
00069 }
00070
00072 void
00073 user_flush_data (png_structp)
00074 {
00075 }
00076 }
00077
00078 namespace pcl
00079 {
00080 namespace io
00081 {
00083 template<typename T> void
00084 encodeImageToPNG (typename std::vector<T>& image_arg,
00085 size_t width_arg,
00086 size_t height_arg,
00087 int image_format_arg,
00088 typename std::vector<uint8_t>& pngData_arg,
00089 int png_level_arg)
00090 {
00091 png_structp png_ptr;
00092 png_infop info_ptr;
00093 volatile int channels;
00094
00095 if (image_arg.size () ==0)
00096 return;
00097
00098
00099 switch (image_format_arg)
00100 {
00101 case PNG_COLOR_TYPE_GRAY:
00102 channels = 1;
00103 break;
00104 case PNG_COLOR_TYPE_GRAY_ALPHA:
00105 channels = 2;
00106 break;
00107 case PNG_COLOR_TYPE_RGB:
00108 channels = 3;
00109 break;
00110 case PNG_COLOR_TYPE_RGB_ALPHA:
00111 channels = 4;
00112 break;
00113 default:
00114 channels = 0;
00115 break;
00116 }
00117
00118
00119 assert (image_arg.size () == width_arg*height_arg*channels);
00120
00121
00122 png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
00123 assert (png_ptr && "creating png_create_write_structpng_create_write_struct failed");
00124
00125
00126 info_ptr = png_create_info_struct (png_ptr);
00127 assert (info_ptr && "Could not allocate info struct");
00128
00129
00130 setjmp(png_jmpbuf(png_ptr));
00131
00132
00133 pngData_arg.clear ();
00134 pngData_arg.reserve (300 * 1024);
00135
00136
00137 png_set_write_fn (png_ptr, reinterpret_cast<void*> (&pngData_arg),
00138 user_write_data, user_flush_data);
00139
00140
00141 if (png_level_arg >= 0)
00142 {
00143 png_set_compression_level (png_ptr, png_level_arg);
00144 }
00145 else
00146 {
00147 png_set_compression_level (png_ptr, Z_DEFAULT_COMPRESSION);
00148 }
00149
00150
00151 png_set_IHDR (png_ptr, info_ptr,
00152 static_cast<png_uint_32> (width_arg), static_cast<png_uint_32> (height_arg),
00153 sizeof(T) * 8,
00154 image_format_arg, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
00155 PNG_FILTER_TYPE_DEFAULT);
00156
00157 png_write_info (png_ptr, info_ptr);
00158
00159
00160 size_t y;
00161 for (y = 0; y < height_arg; y++)
00162 {
00163 png_write_row (png_ptr, reinterpret_cast<png_bytep> (&image_arg[y * width_arg * channels]));
00164 }
00165
00166
00167 png_write_end (png_ptr, 0);
00168
00169 if (info_ptr)
00170 png_free_data (png_ptr, info_ptr, PNG_FREE_ALL, -1);
00171 if (png_ptr)
00172 png_destroy_write_struct (&png_ptr, 0);
00173 }
00174
00176 template<typename T> void
00177 decodePNGImage (typename std::vector<uint8_t>& pngData_arg,
00178 typename std::vector<T>& imageData_arg,
00179 size_t& width_arg,
00180 size_t& height_arg,
00181 unsigned int& channels_arg)
00182 {
00183 int y;
00184 png_structp png_ptr;
00185 png_infop info_ptr;
00186 png_uint_32 png_width;
00187 png_uint_32 png_height;
00188 int png_bit_depth, png_color_type, png_interlace_type;
00189
00190 png_bytep * row_pointers;
00191
00192 if (pngData_arg.size () == 0)
00193 return;
00194
00195 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
00196 assert (png_ptr && "creating png_create_write_structpng_create_write_struct failed");
00197
00198
00199 info_ptr = png_create_info_struct (png_ptr);
00200 assert(info_ptr && "Could not allocate info struct");
00201
00202
00203 setjmp (png_jmpbuf(png_ptr));
00204
00205 uint8_t* input_pointer = &pngData_arg[0];
00206 png_set_read_fn (png_ptr, reinterpret_cast<void*> (&input_pointer), user_read_data);
00207
00208 png_read_info (png_ptr, info_ptr);
00209
00210 png_get_IHDR (png_ptr, info_ptr, &png_width, &png_height, &png_bit_depth,
00211 &png_color_type, &png_interlace_type, NULL, NULL);
00212
00213
00214 assert(png_bit_depth==sizeof(T)*8);
00215
00216 unsigned int png_channels;
00217 switch (png_color_type)
00218 {
00219 case PNG_COLOR_TYPE_GRAY:
00220 png_channels = 1;
00221 break;
00222 case PNG_COLOR_TYPE_GRAY_ALPHA:
00223 png_channels = 2;
00224 break;
00225 case PNG_COLOR_TYPE_RGB:
00226 png_channels = 3;
00227 break;
00228 case PNG_COLOR_TYPE_RGB_ALPHA:
00229 png_channels = 4;
00230 break;
00231 default:
00232 png_channels = 0;
00233 break;
00234 }
00235
00236 width_arg = png_width;
00237 height_arg = png_height;
00238 channels_arg = png_channels;
00239
00240 imageData_arg.clear ();
00241 imageData_arg.resize (png_height * png_width * png_channels);
00242
00243 row_pointers = reinterpret_cast<png_bytep*> (malloc (sizeof(png_bytep) * png_height));
00244
00245 for (y = 0; y < png_height; y++)
00246 row_pointers[y] = reinterpret_cast<png_byte*> (&imageData_arg[y * png_width * png_channels]);
00247
00248 png_read_image (png_ptr, row_pointers);
00249
00250 if (info_ptr)
00251 png_free_data (png_ptr, info_ptr, PNG_FREE_ALL, -1);
00252 if (png_ptr)
00253 png_destroy_read_struct (&png_ptr, 0, 0);
00254 if (row_pointers)
00255 free (row_pointers);
00256 }
00257 }
00258 }
00259
00260
00262 void
00263 pcl::io::encodeMonoImageToPNG (std::vector<uint8_t>& image_arg,
00264 size_t width_arg,
00265 size_t height_arg,
00266 std::vector<uint8_t>& pngData_arg,
00267 int png_level_arg)
00268 {
00269 encodeImageToPNG<uint8_t> (image_arg,
00270 static_cast<png_uint_32> (width_arg), static_cast<png_uint_32> (height_arg),
00271 PNG_COLOR_TYPE_GRAY, pngData_arg, png_level_arg);
00272 }
00273
00275 void
00276 pcl::io::encodeMonoImageToPNG (std::vector<uint16_t>& image_arg,
00277 size_t width_arg,
00278 size_t height_arg,
00279 std::vector<uint8_t>& pngData_arg,
00280 int png_level_arg)
00281 {
00282 encodeImageToPNG<uint16_t> (image_arg,
00283 static_cast<png_uint_32> (width_arg), static_cast<png_uint_32> (height_arg),
00284 PNG_COLOR_TYPE_GRAY, pngData_arg, png_level_arg);
00285 }
00286
00288 void
00289 pcl::io::encodeRGBImageToPNG (std::vector<uint8_t>& image_arg,
00290 size_t width_arg,
00291 size_t height_arg,
00292 std::vector<uint8_t>& pngData_arg,
00293 int png_level_arg)
00294 {
00295 encodeImageToPNG<uint8_t>(image_arg,
00296 static_cast<png_uint_32> (width_arg), static_cast<png_uint_32> (height_arg),
00297 PNG_COLOR_TYPE_RGB, pngData_arg, png_level_arg);
00298 }
00299
00301 void
00302 pcl::io::encodeRGBImageToPNG (std::vector<uint16_t>& image_arg,
00303 size_t width_arg,
00304 size_t height_arg,
00305 std::vector<uint8_t>& pngData_arg,
00306 int png_level_arg)
00307 {
00308 encodeImageToPNG<uint16_t>(image_arg,
00309 static_cast<png_uint_32> (width_arg), static_cast<png_uint_32> (height_arg),
00310 PNG_COLOR_TYPE_RGB, pngData_arg, png_level_arg);
00311 }
00312
00314 void
00315 pcl::io::decodePNGToImage (std::vector<uint8_t>& pngData_arg,
00316 std::vector<uint8_t>& imageData_arg,
00317 size_t& width_arg,
00318 size_t& height_arg,
00319 unsigned int& channels_arg)
00320 {
00321 decodePNGImage<uint8_t> (pngData_arg, imageData_arg, width_arg, height_arg, channels_arg);
00322 }
00323
00325 void
00326 pcl::io::decodePNGToImage (std::vector<uint8_t>& pngData_arg,
00327 std::vector<uint16_t>& imageData_arg,
00328 size_t& width_arg,
00329 size_t& height_arg,
00330 unsigned int& channels_arg)
00331 {
00332 decodePNGImage<uint16_t> (pngData_arg, imageData_arg, width_arg, height_arg, channels_arg);
00333 }
00334