|
degate 0.1.1
|
00001 /* -*-c++-*- 00002 00003 This file is part of the IC reverse engineering tool degate. 00004 00005 Copyright 2008, 2009, 2010 by Martin Schobert 00006 00007 Degate is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 any later version. 00011 00012 Degate is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with degate. If not, see <http://www.gnu.org/licenses/>. 00019 00020 */ 00021 00022 #ifndef __IMAGEHELPER_H__ 00023 #define __IMAGEHELPER_H__ 00024 00025 #include <ImageReaderFactory.h> 00026 #include <ImageReaderBase.h> 00027 #include <ImageWriterBase.h> 00028 #include <TIFFWriter.h> 00029 #include <PixelPolicies.h> 00030 #include <StoragePolicies.h> 00031 #include <Image.h> 00032 00033 #include <set> 00034 #include <boost/foreach.hpp> 00035 00036 namespace degate { 00037 00038 00039 /** 00040 * Load an image in a common image format, such as tiff. 00041 * @exception InvalidPathException Thrown if, path does not exists. 00042 * @exception DegateRuntimeException This exception is thrown, if there is 00043 * no matching image importer or if the import failed. 00044 */ 00045 00046 template<typename ImageType> 00047 std::tr1::shared_ptr<ImageType> load_image(std::string const& path) { 00048 if(!file_exists(path)) { 00049 boost::format fmter("Error in load_image(): file %1% does not exist."); 00050 fmter % path; 00051 throw InvalidPathException(fmter.str()); 00052 } 00053 else { 00054 boost::format fmter("Error in load_image(): The image file %1% cannot be loaded."); 00055 fmter % path; 00056 00057 // get a reader 00058 ImageReaderFactory<ImageType> ir_factory; 00059 std::tr1::shared_ptr<ImageReaderBase<ImageType> > reader = ir_factory.get_reader(path); 00060 00061 if(reader->read() == false) { 00062 throw DegateRuntimeException(fmter.str()); 00063 } 00064 else { 00065 00066 debug(TM, "reading image file: %s", path.c_str()); 00067 00068 // create an empty image 00069 std::tr1::shared_ptr<ImageType> img(new ImageType(reader->get_width(), 00070 reader->get_height())); 00071 if(reader->get_image(img) == true) 00072 return img; 00073 else 00074 throw DegateRuntimeException(fmter.str()); 00075 } 00076 } 00077 } 00078 00079 /** 00080 * Load an image in a common image format, such as tiff, into an existing degate image. 00081 * @exception InvalidPointerException This exception is thrown, if parameter \p img represents an invalid pointer. 00082 */ 00083 00084 template<typename ImageType> 00085 void load_image(std::string const& path, std::tr1::shared_ptr<ImageType> img) { 00086 00087 if(img == NULL) throw InvalidPointerException("invalid image pointer"); 00088 std::tr1::shared_ptr<ImageType> i = load_image<ImageType>(path); 00089 copy_image<ImageType, ImageType>(img, i); 00090 } 00091 00092 00093 /** 00094 * Store an image in a common file format. 00095 * Only the tiff file format is supported. 00096 * @todo We should use a factory for writer objects. 00097 * @exception DegateRuntimeException This exception is thrown, if the writer failed to save the image. 00098 * @exception InvalidPointerException This exception is thrown, if parameter \p img represents an invalid pointer. 00099 */ 00100 00101 template<typename ImageType> 00102 void save_image(std::string const& path, std::tr1::shared_ptr<ImageType> img) { 00103 00104 if(img == NULL) throw InvalidPointerException("invalid image pointer"); 00105 TIFFWriter<ImageType> tiff_writer(img->get_width(), 00106 img->get_height(), path); 00107 if(tiff_writer.write_image(img) != true) { 00108 boost::format fmter("Error in save_image(): Cannot write file %1%."); 00109 fmter % path; 00110 throw DegateRuntimeException(fmter.str()); 00111 } 00112 } 00113 00114 /** 00115 * Save a part of an image. 00116 * @exception InvalidPointerException This exception is thrown, if parameter \p img represents an invalid pointer. 00117 */ 00118 template<typename ImageType> 00119 void save_part_of_image(std::string const& path, 00120 std::tr1::shared_ptr<ImageType> img, 00121 BoundingBox const& bounding_box) { 00122 00123 if(img == NULL) throw InvalidPointerException("invalid image pointer"); 00124 std::tr1::shared_ptr<ImageType> part(new ImageType(bounding_box.get_width(), 00125 bounding_box.get_height())); 00126 00127 extract_partial_image(part, img, bounding_box); 00128 save_image(path, part); 00129 } 00130 00131 /** 00132 * Normalize a single channel image and store it in a common file format. 00133 * Only the tiff file format is supported. 00134 * @exception InvalidPointerException This exception is thrown, if parameter \p img represents an invalid pointer. 00135 */ 00136 00137 template<typename ImageType> 00138 void save_normalized_image(std::string const& path, std::tr1::shared_ptr<ImageType> img) { 00139 00140 if(img == NULL) throw InvalidPointerException("invalid image pointer"); 00141 std::tr1::shared_ptr<ImageType> normalized_img(new ImageType(img->get_width(), 00142 img->get_height())); 00143 00144 normalize<ImageType, ImageType>(normalized_img, img, 0, 255); 00145 00146 save_image<ImageType>(path, normalized_img); 00147 } 00148 00149 00150 /** 00151 * Merge a set of images by averaging them. 00152 * @exception DegateRuntimeException This exception is thrown, if images differ in size. 00153 * @return If image collection \p images contains elements, this function returns a 00154 * valid merged image. If the collection is empty, a NULL pointer is returned. 00155 */ 00156 template<typename ImageType> 00157 std::tr1::shared_ptr<ImageType> merge_images(std::list<std::tr1::shared_ptr<ImageType> > const & images) { 00158 00159 std::tr1::shared_ptr<ImageType> new_img; 00160 if(images.empty()) return new_img; 00161 00162 const std::tr1::shared_ptr<ImageType> img = images.front(); 00163 00164 unsigned int w = img->get_width(), h = img->get_height(); 00165 std::vector<double> i_tmp(4 * w * h); 00166 00167 BOOST_FOREACH(const std::tr1::shared_ptr<ImageType> i, images) { 00168 00169 // verify that all images have the same dimensions 00170 if(w != i->get_width() || h != i->get_height()) 00171 throw DegateRuntimeException("merge_images() failed, because images differ in size."); 00172 00173 for(unsigned int y = 0; y < h; y++) 00174 for(unsigned int x = 0; x < w; x++) { 00175 color_t pix = i->get_pixel_as<color_t>(x, y); 00176 unsigned int offs = 4 * (y * w + x); 00177 i_tmp[offs] += MASK_R(pix); 00178 i_tmp[offs+1] += MASK_G(pix); 00179 i_tmp[offs+2] += MASK_B(pix); 00180 i_tmp[offs+3] += MASK_A(pix); 00181 } 00182 } 00183 00184 const double elems = images.size(); 00185 00186 new_img = std::tr1::shared_ptr<ImageType>(new GateTemplateImage(w, h)); 00187 assert(new_img != NULL); 00188 00189 for(unsigned int y = 0; y < h; y++) 00190 for(unsigned int x = 0; x < w; x++) { 00191 unsigned int offs = 4 * (y * w + x); 00192 color_t pix = MERGE_CHANNELS(lround(i_tmp[offs] / elems), 00193 lround(i_tmp[offs+1] / elems), 00194 lround(i_tmp[offs+2] / elems), 00195 lround(i_tmp[offs+3] / elems)); 00196 new_img->set_pixel(x, y, pix); 00197 } 00198 00199 return new_img; 00200 } 00201 00202 00203 } 00204 00205 #endif
1.7.4