$search
00001 /********************************************************************* 00002 * 00003 * Software License Agreement (BSD License) 00004 * 00005 * Copyright (c) 2011, Robert Bosch LLC. 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * * Redistributions in binary form must reproduce the above 00015 * copyright notice, this list of conditions and the following 00016 * disclaimer in the documentation and/or other materials provided 00017 * with the distribution. 00018 * * Neither the name of the Robert Bosch nor the names of its 00019 * contributors may be used to endorse or promote products derived 00020 * from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00028 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00029 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00030 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00032 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00033 * POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 *********************************************************************/ 00036 00037 #include <stdio.h> 00038 #include <string.h> 00039 #include <algorithm> 00040 #include <map> 00041 #include <typeinfo> 00042 00043 #include "vlr/vlrException.h" 00044 #include "vlr/vlrImage.h" 00045 00046 namespace vlr { 00047 00048 template<class T> 00049 Image<T>::Image(uint32_t width, uint32_t height, uint32_t channels, uint32_t padded_width, bool manage_buffer, colorSpace_t colorSpace) : 00050 ImageBase(width, height, channels, padded_width, manage_buffer, colorSpace) { 00051 create(); 00052 } 00053 00054 template<class T> 00055 Image<T>::Image(uint32_t width, uint32_t height, uint32_t channels, colorSpace_t colorSpace) : 00056 ImageBase(width, height, channels, width, true, colorSpace) { 00057 create(); 00058 } 00059 00060 template<class T> 00061 Image<T>::Image(uint32_t width, uint32_t height, uint32_t channels) : 00062 ImageBase(width, height, channels, width, true, CS_GRAY) { 00063 create(); 00064 } 00065 00066 template<class T> 00067 Image<T>::Image(uint32_t width, uint32_t height) : 00068 ImageBase(width, height, 1, width, true, CS_GRAY) { 00069 create(); 00070 } 00071 00072 template<class T> 00073 void Image<T>::create() { 00074 element_size_ = sizeof(T); 00075 if (manage_buffer_ && num_elements_ > 0) { 00076 data_ = new T[num_elements_]; 00077 } 00078 type_name_ = typeid(*this).name(); 00079 } 00080 00081 template<class T> 00082 Image<T>::Image(const Image& img, bool ignoreManageBuffer, bool copyData, bool copyTags) : 00083 ImageBase(img.width_, img.height_, img.channels_, img.padded_width_, img.manage_buffer_, img.color_space_) { 00084 00085 if (ignoreManageBuffer) { 00086 manage_buffer_ = true; 00087 } // create a buffer for the data regardless of source 00088 create(); 00089 if (manage_buffer_ && num_elements_ > 0) { 00090 if (copyData) { 00091 memcpy(data_, img.data_, num_elements_ * element_size_); 00092 } 00093 } 00094 if (copyTags) { 00095 tags_ = img.tags_; 00096 } 00097 } 00098 00099 template<class T> 00100 Image<T>& Image<T>::operator=(const Image<T>& img) { 00101 if (this == &img) { 00102 return *this; 00103 } 00104 00105 // TODO: assigment operator always creates deep copy 00106 if (!sameDims(img) || !manage_buffer_) 00107 // {throw("assignment failed: images have different dimensions");} 00108 { 00109 T* tmp = 0; 00110 00111 if (num_elements_ > 0) { 00112 tmp = new T[num_elements_]; 00113 } 00114 if (data_ && manage_buffer_) { 00115 delete[] data_; 00116 } 00117 00118 data_ = tmp; 00119 width_ = img.width(); 00120 height_ = img.height(); 00121 channels_ = img.channels(); 00122 padded_width_ = img.paddedWidth(); 00123 manage_buffer_ = true; 00124 } 00125 00126 if (num_elements_ > 0) { 00127 memcpy(data_, img.data_, num_elements_ * element_size_); 00128 } 00129 00130 tags_ = img.tags_; 00131 color_space_ = img.colorSpace(); 00132 00133 return *this; 00134 } 00135 00136 template<class T> 00137 Image<T>::~Image() { 00138 if (data_ && manage_buffer_) { 00139 delete[] data_; 00140 } 00141 } 00142 00143 template<class T> 00144 void Image<T>::bounds(T& lowerBound, T& upperBound) { 00145 T* data_ptr = data_; 00146 00147 uint32_t align_gap = padded_width_ - width_; 00148 00149 lowerBound = upperBound = *data_ptr; 00150 00151 for (uint32_t c = 0; c < channels_; c++) { 00152 for (uint32_t y = 0; y < height_; y++) { 00153 for (uint32_t x = 0; x < width_; x++) { 00154 if (*data_ptr < lowerBound) { 00155 lowerBound = *data_ptr; 00156 } 00157 else if (*data_ptr > upperBound) { 00158 upperBound = *data_ptr; 00159 } 00160 data_ptr++; 00161 } 00162 data_ptr += align_gap; 00163 } 00164 } 00165 } 00166 00167 template<class T> 00168 void Image<T>::normalize(T newMin, T newMax) { 00169 T imgMinVal, imgMaxVal, dFactor; 00170 00171 if (!data_) { 00172 throw VLRException("Zero data pointer."); 00173 } 00174 00175 T* data_ptr = data_; 00176 00177 uint32_t align_gap = padded_width_ - width_; 00178 00179 bounds(imgMinVal, imgMaxVal); 00180 00181 if (imgMaxVal == imgMinVal) { 00182 return; 00183 } 00184 00185 dFactor = (newMax - newMin) / (imgMaxVal - imgMinVal); 00186 00187 for (uint32_t c = 0; c < channels_; c++) { 00188 for (uint32_t y = 0; y < height_; y++) { 00189 for (uint32_t x = 0; x < width_; x++) { 00190 *data_ptr = (*data_ptr - imgMinVal) * dFactor + newMin; 00191 data_ptr++; 00192 } 00193 00194 data_ptr += align_gap; 00195 } 00196 } 00197 } 00198 00199 template<class T> 00200 Image<T> Image<T>::operator +(const Image<T>& img) const { 00201 if (!sameDims(img)) { 00202 throw VLRException("Different image dimensions."); 00203 } 00204 00205 Image<T> res = Image<T> (*this); // TODO: Implement tag class filtering... 00206 const T* data1 = data_; 00207 const T* data2 = const_cast<Image<T>*> (&img)->data(); 00208 T* resdata = res.data(); 00209 for (uint32_t i = 0; i < num_elements_; i++) { 00210 *resdata++ = *data1++ + *data2++; 00211 } 00212 00213 return res; 00214 } 00215 00216 template<class T> 00217 bool Image<T>::reformat(uint32_t new_width, uint32_t new_height, uint32_t new_channels, uint32_t new_padded_width, colorSpace_t new_color_space) 00218 00219 { 00220 if (new_color_space != CS_GRAY && new_channels < 3) { 00221 return false; 00222 } 00223 00224 color_space_ = new_color_space; 00225 00226 if (new_width == width_ && new_height == height_ && new_channels == channels_ && new_padded_width == padded_width_) { 00227 return true; 00228 } 00229 00230 if (data_ && manage_buffer_) { 00231 delete[] data_; 00232 data_ = NULL; 00233 } 00234 00235 width_ = new_width; 00236 height_ = new_height; 00237 channels_ = new_channels; 00238 padded_width_ = new_padded_width; 00239 manage_buffer_ = true; 00240 00241 num_elements_ = padded_width_ * height_ * channels_; 00242 00243 if (num_elements_ > 0) { 00244 data_ = new T[num_elements_]; 00245 } 00246 tags_.clear(); 00247 return true; 00248 } 00249 00250 template<class T> 00251 Image<T> Image<T>::operator ()(uint32_t x, uint32_t y, uint32_t roi_width, uint32_t roi_height) const { 00252 00253 if (roi_width == 0 || roi_height == 0 || x + roi_width > width_ || y + roi_height > height_) { 00254 throw VLRException("Illegal roi dimensions."); 00255 } 00256 00257 Image<T> res(roi_width, roi_height, channels_, padded_width_, false, color_space_); 00258 res.data_ = &data_[y * padded_width_ + x]; 00259 00260 return res; 00261 } 00262 00263 // instantiations for supported data types 00264 template class Image<uint8_t> ; 00265 template class Image<int8_t> ; 00266 template class Image<char> ; // should be int8_t ?!? 00267 template class Image<uint16_t> ; 00268 template class Image<int16_t> ; 00269 template class Image<uint32_t> ; 00270 template class Image<int32_t> ; 00271 template class Image<float> ; 00272 template class Image<double> ; 00273 } // namespace vlr