1 /*M/////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 // 5 // By downloading, copying, installing or using the software you agree to this license. 6 // If you do not agree to this license, do not download, install, 7 // copy or use the software. 8 // 9 // 10 // License Agreement 11 // For Open Source Computer Vision Library 12 // 13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. 14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved. 15 // Third party copyrights are property of their respective owners. 16 // 17 // Redistribution and use in source and binary forms, with or without modification, 18 // are permitted provided that the following conditions are met: 19 // 20 // * Redistribution's of source code must retain the above copyright notice, 21 // this list of conditions and the following disclaimer. 22 // 23 // * Redistribution's in binary form must reproduce the above copyright notice, 24 // this list of conditions and the following disclaimer in the documentation 25 // and/or other materials provided with the distribution. 26 // 27 // * The name of the copyright holders may not be used to endorse or promote products 28 // derived from this software without specific prior written permission. 29 // 30 // This software is provided by the copyright holders and contributors "as is" and 31 // any express or implied warranties, including, but not limited to, the implied 32 // warranties of merchantability and fitness for a particular purpose are disclaimed. 33 // In no event shall the Intel Corporation or contributors be liable for any direct, 34 // indirect, incidental, special, exemplary, or consequential damages 35 // (including, but not limited to, procurement of substitute goods or services; 36 // loss of use, data, or profits; or business interruption) however caused 37 // and on any theory of liability, whether in contract, strict liability, 38 // or tort (including negligence or otherwise) arising in any way out of 39 // the use of this software, even if advised of the possibility of such damage. 40 // 41 //M*/ 42 43 #ifdef HAVE_WEBP 44 45 #include "precomp.hpp" 46 47 #include <webp/decode.h> 48 #include <webp/encode.h> 49 50 #include <stdio.h> 51 #include <limits.h> 52 53 #include "grfmt_webp.hpp" 54 55 #include "opencv2/imgproc.hpp" 56 57 const size_t WEBP_HEADER_SIZE = 32; 58 59 namespace cv 60 { 61 62 WebPDecoder::WebPDecoder() 63 { 64 m_buf_supported = true; 65 } 66 67 WebPDecoder::~WebPDecoder() {} 68 69 size_t WebPDecoder::signatureLength() const 70 { 71 return WEBP_HEADER_SIZE; 72 } 73 74 bool WebPDecoder::checkSignature(const String & signature) const 75 { 76 bool ret = false; 77 78 if(signature.size() >= WEBP_HEADER_SIZE) 79 { 80 WebPBitstreamFeatures features; 81 if(VP8_STATUS_OK == WebPGetFeatures((uint8_t *)signature.c_str(), 82 WEBP_HEADER_SIZE, &features)) 83 { 84 ret = true; 85 } 86 } 87 88 return ret; 89 } 90 91 ImageDecoder WebPDecoder::newDecoder() const 92 { 93 return makePtr<WebPDecoder>(); 94 } 95 96 bool WebPDecoder::readHeader() 97 { 98 if (m_buf.empty()) 99 { 100 FILE * wfile = NULL; 101 102 wfile = fopen(m_filename.c_str(), "rb"); 103 104 if(wfile == NULL) 105 { 106 return false; 107 } 108 109 fseek(wfile, 0, SEEK_END); 110 long int wfile_size = ftell(wfile); 111 fseek(wfile, 0, SEEK_SET); 112 113 if(wfile_size > static_cast<long int>(INT_MAX)) 114 { 115 fclose(wfile); 116 return false; 117 } 118 119 data.create(1, wfile_size, CV_8U); 120 121 size_t data_size = fread(data.ptr(), 1, wfile_size, wfile); 122 123 if(wfile) 124 { 125 fclose(wfile); 126 } 127 128 if(static_cast<long int>(data_size) != wfile_size) 129 { 130 return false; 131 } 132 } 133 else 134 { 135 data = m_buf; 136 } 137 138 WebPBitstreamFeatures features; 139 if(VP8_STATUS_OK == WebPGetFeatures(data.ptr(), WEBP_HEADER_SIZE, &features)) 140 { 141 m_width = features.width; 142 m_height = features.height; 143 144 if (features.has_alpha) 145 { 146 m_type = CV_8UC4; 147 channels = 4; 148 } 149 else 150 { 151 m_type = CV_8UC3; 152 channels = 3; 153 } 154 155 return true; 156 } 157 158 return false; 159 } 160 161 bool WebPDecoder::readData(Mat &img) 162 { 163 if( m_width > 0 && m_height > 0 ) 164 { 165 if (img.cols != m_width || img.rows != m_height || img.type() != m_type) 166 { 167 img.create(m_height, m_width, m_type); 168 } 169 170 uchar* out_data = img.ptr(); 171 size_t out_data_size = img.cols * img.rows * img.elemSize(); 172 173 uchar *res_ptr = 0; 174 if (channels == 3) 175 { 176 res_ptr = WebPDecodeBGRInto(data.ptr(), data.total(), out_data, 177 (int)out_data_size, (int)img.step); 178 } 179 else if (channels == 4) 180 { 181 res_ptr = WebPDecodeBGRAInto(data.ptr(), data.total(), out_data, 182 (int)out_data_size, (int)img.step); 183 } 184 185 if(res_ptr == out_data) 186 { 187 return true; 188 } 189 } 190 191 return false; 192 } 193 194 WebPEncoder::WebPEncoder() 195 { 196 m_description = "WebP files (*.webp)"; 197 m_buf_supported = true; 198 } 199 200 WebPEncoder::~WebPEncoder() { } 201 202 ImageEncoder WebPEncoder::newEncoder() const 203 { 204 return makePtr<WebPEncoder>(); 205 } 206 207 bool WebPEncoder::write(const Mat& img, const std::vector<int>& params) 208 { 209 int channels = img.channels(), depth = img.depth(); 210 int width = img.cols, height = img.rows; 211 212 const Mat *image = &img; 213 Mat temp; 214 size_t size = 0; 215 216 bool comp_lossless = true; 217 float quality = 100.0f; 218 219 if (params.size() > 1) 220 { 221 if (params[0] == CV_IMWRITE_WEBP_QUALITY) 222 { 223 comp_lossless = false; 224 quality = static_cast<float>(params[1]); 225 if (quality < 1.0f) 226 { 227 quality = 1.0f; 228 } 229 if (quality > 100.0f) 230 { 231 comp_lossless = true; 232 } 233 } 234 } 235 236 uint8_t *out = NULL; 237 238 if(depth != CV_8U) 239 { 240 return false; 241 } 242 243 if(channels == 1) 244 { 245 cvtColor(*image, temp, CV_GRAY2BGR); 246 image = &temp; 247 channels = 3; 248 } 249 else if (channels == 2) 250 { 251 return false; 252 } 253 254 if (comp_lossless) 255 { 256 if(channels == 3) 257 { 258 size = WebPEncodeLosslessBGR(image->ptr(), width, height, (int)image->step, &out); 259 } 260 else if(channels == 4) 261 { 262 size = WebPEncodeLosslessBGRA(image->ptr(), width, height, (int)image->step, &out); 263 } 264 } 265 else 266 { 267 if(channels == 3) 268 { 269 size = WebPEncodeBGR(image->ptr(), width, height, (int)image->step, quality, &out); 270 } 271 else if(channels == 4) 272 { 273 size = WebPEncodeBGRA(image->ptr(), width, height, (int)image->step, quality, &out); 274 } 275 } 276 277 if(size > 0) 278 { 279 if(m_buf) 280 { 281 m_buf->resize(size); 282 memcpy(&(*m_buf)[0], out, size); 283 } 284 else 285 { 286 FILE *fd = fopen(m_filename.c_str(), "wb"); 287 if(fd != NULL) 288 { 289 fwrite(out, size, sizeof(uint8_t), fd); 290 fclose(fd); fd = NULL; 291 } 292 } 293 } 294 295 if (out != NULL) 296 { 297 free(out); 298 out = NULL; 299 } 300 301 return size > 0; 302 } 303 304 } 305 306 #endif 307