|
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 __SCALINGMANAGER_H__ 00023 #define __SCALINGMANAGER_H__ 00024 00025 #include "Image.h" 00026 00027 #include <map> 00028 #include <assert.h> 00029 #include <algorithm> 00030 00031 namespace degate { 00032 00033 /** 00034 * The ScalingManager creates prescaled images for a master image. 00035 * You can use the ScalingManager only for images of type TileImage. 00036 * If you want to scale images for yourself, please check out method 00037 * scale_down(). 00038 * 00039 * @see ImageManipulation::scale_down() 00040 */ 00041 template<class ImageType> 00042 class ScalingManager { 00043 00044 public: 00045 00046 typedef std::pair<double, std::tr1::shared_ptr<ImageType> > image_map_element; 00047 typedef std::map<double, /* scaling */ 00048 std::tr1::shared_ptr<ImageType> > image_map; 00049 00050 private: 00051 std::string base_directory; 00052 00053 image_map images; 00054 00055 unsigned int min_size; 00056 00057 private: 00058 00059 unsigned long get_nearest_power_of_two(unsigned int value) { 00060 unsigned int i = 1; 00061 00062 if (value == 0) return 1; 00063 for (;;) { 00064 if (value == 1) return i; 00065 else if (value == 3) return i*4; 00066 value >>= 1; 00067 i *= 2; 00068 } 00069 } 00070 00071 00072 public: 00073 00074 typedef std::list<double> zoom_step_list; 00075 00076 /** 00077 * Create a new ScalingManager object for an image. 00078 * @param img The background image. 00079 * @param base_directory A directory where all files can be stored. You 00080 * can use the directory of the master image for that. Make 00081 * sure that the directory exist. if you compile libdegate 00082 * with DEBUG=1 the existence is assert()ed. 00083 * @param min_size Create down scalings until the edge length 00084 * is becomes less than \p min_size. 00085 */ 00086 ScalingManager(std::tr1::shared_ptr<ImageType> img, 00087 std::string const& base_directory, 00088 int min_size = 1024) { 00089 00090 assert(img != NULL); 00091 this->base_directory = base_directory; 00092 images[1] = img; 00093 this->min_size = min_size; 00094 00095 assert(file_exists(base_directory)); 00096 } 00097 00098 /** 00099 * Destroy a scaling manager. This will destroy images anf their files 00100 * and directories if the imag is not persistent. 00101 */ 00102 ~ScalingManager() {} 00103 00104 /** 00105 * Get a list of available zoom steps. 00106 * @return Returns a std::list<double> with the zoom steps. A value larger 00107 * than 1 indicates a downscaled version. The non scaled version with 00108 * scale factor 1.0 is stored in the list, too. 00109 */ 00110 const zoom_step_list get_zoom_steps() const { 00111 zoom_step_list steps; 00112 00113 for(typename image_map::const_iterator iter = images.begin(); 00114 iter != images.end(); ++iter) 00115 steps.push_back((*iter).first); 00116 00117 steps.sort(); 00118 return steps; 00119 } 00120 00121 /** 00122 * Create the scaled images. 00123 * Created prescaled images that have the same peristence state as the 00124 * master image. The files are written into the directory, where the 00125 * master image is stored. 00126 * @throw InvalidPathException This exception is thrown, if the 00127 * \p directory (ctor param) doesn't exists. 00128 * @todo If the image was already scaled, do not do it again. Maybe we need a force option. 00129 */ 00130 void create_scalings() { 00131 if(!(file_exists(base_directory) && is_directory(base_directory))) 00132 throw InvalidPathException("The directory for prescaled images must exist. but it is not there."); 00133 00134 std::tr1::shared_ptr<ImageType> last_img = images[1]; 00135 unsigned int w = last_img->get_width(); 00136 unsigned int h = last_img->get_height(); 00137 00138 for(int i = 2; ((h > min_size) || (w > min_size)) && 00139 (i < (1<<24)); // max 24 scaling levels 00140 i*=2) { 00141 00142 w >>= 1; 00143 h >>= 1; 00144 00145 // create a new image 00146 char dir_name[PATH_MAX]; 00147 snprintf(dir_name, sizeof(dir_name), "scaling_%d.dimg", i); 00148 std::string dir_path = join_pathes(images[1]->get_directory(), std::string(dir_name)); 00149 00150 debug(TM, "create scaled image in %s for scaling factor %d?", dir_path.c_str(), i); 00151 if(!file_exists(dir_path)) { 00152 debug(TM, "yes"); 00153 create_directory(dir_path); 00154 00155 std::tr1::shared_ptr<ImageType> new_img(new ImageType(w, h, dir_path, 00156 images[1]->is_persistent())); 00157 00158 scale_down_by_2<ImageType, ImageType>(new_img, last_img); 00159 last_img = new_img; 00160 } 00161 else { 00162 debug(TM, "no"); 00163 std::tr1::shared_ptr<ImageType> new_img(new ImageType(w, h, dir_path, 00164 images[1]->is_persistent())); 00165 00166 last_img = new_img; 00167 } 00168 images[i] = last_img; 00169 } 00170 } 00171 00172 /** 00173 * Get the image with the nearest scaling value to the requested scaling. 00174 * @return Returns a std::pair<double, shared_ptr> with the scaling 00175 * factor and a shared pointer to the image. 00176 */ 00177 image_map_element get_image(double request_scaling) { 00178 unsigned int factor; 00179 if(request_scaling > 1) { 00180 factor = std::min(get_nearest_power_of_two(lrint(request_scaling)), 00181 (unsigned long)lrint(images.rbegin()->first)); 00182 typename image_map::iterator found = images.find(factor); 00183 assert(found != images.end()); 00184 //debug(TM, "requested scaling is %f. nearest scaling is %d. found image with scaling %f", request_scaling, factor, found->first); 00185 return *found; 00186 } 00187 00188 //debug(TM, "return normal image"); 00189 return image_map_element(1, images[1]); 00190 } 00191 00192 }; 00193 00194 /** 00195 * A typedef for scaling managers that handle background images. 00196 */ 00197 typedef std::tr1::shared_ptr<ScalingManager<BackgroundImage> > ScalingManager_shptr; 00198 } 00199 00200 #endif
1.7.4