degate  0.1.2
TileImage.h
Go to the documentation of this file.
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 __TILEIMAGE_H__
00023 #define __TILEIMAGE_H__
00024 
00025 #include "globals.h"
00026 #include "PixelPolicies.h"
00027 #include "StoragePolicies.h"
00028 #include "FileSystem.h"
00029 #include "TileCache.h"
00030 
00031 namespace degate {
00032 
00033   /**
00034    * Storage policy for image objects that consists of tiles.
00035    *
00036    * This implementation uses a TileCache.
00037    */
00038 
00039   template<class PixelPolicy>
00040   class StoragePolicy_Tile : public StoragePolicy_Base<PixelPolicy> {
00041 
00042   public:
00043 
00044     typedef std::shared_ptr<MemoryMap<typename PixelPolicy::pixel_type> > MemoryMap_shptr;
00045 
00046   private:
00047 
00048     // Do the underlying file resources have to be cleaned up on destruction?
00049     const bool persistent;
00050 
00051     // Exponent and a bitmask to calculate tile numbers.
00052     const unsigned int tile_width_exp;
00053     const unsigned int offset_bitmask;
00054 
00055     // The place where we store the image data.
00056     const std::string directory;
00057 
00058     // A helper class to load tiles.
00059     mutable TileCache<PixelPolicy> tile_cache;
00060 
00061   private:
00062 
00063 
00064     /**
00065      * Get the minimum width or height of an tile based image, that
00066      * it at least requested_size pixel width / height.
00067      * @param requested_size The minimum size.
00068      * @param tile_width_exp The exponent (to base 2) that gives th
00069      * @return
00070      */
00071     unsigned int calc_real_size(unsigned int requested_size,
00072                                 unsigned int tile_width_exp) const {
00073 
00074       // we can't use the get_tile_size() method here, because we use
00075       // this method during the base class constructor call.
00076       unsigned int tile_size = (1 << tile_width_exp);
00077       unsigned int remainder = requested_size % tile_size;
00078       if(remainder == 0) return requested_size;
00079       else return requested_size - remainder + tile_size;
00080     }
00081 
00082   public:
00083 
00084     /**
00085      * The constructor for a tile based image. The constructed image has at
00086      * least the size specified via the width and height parameter.
00087      * Because the image is splitted into equisized tiles the constructed
00088      * image might be larger than the requested size.
00089      *
00090      * @param _width The minimum width of the image.
00091      * @param _height The minimum height of the image.
00092      * @param _directory A tile based image is stored in multiple
00093      *      files. This directory specifies the place where
00094      *      the files are stored. If the directory doen't exits, it is created.
00095      * @param _persistent This boolean value indicates whether the image files
00096      *      are removed on object destruction.
00097      * @param _tile_width_exp The width (and height) for image tiles. This
00098      *      value is specified as an exponent to the base 2. This means for
00099      *      example that if you want to use a width of 1024 pixel, you have
00100      *      to give a value of 10, because 2^10 is 1024.
00101      */
00102     StoragePolicy_Tile(unsigned int _width, unsigned int _height,
00103                        std::string const& _directory,
00104                        bool _persistent = false,
00105                        unsigned int _tile_width_exp = 10) :
00106       persistent(_persistent),
00107       tile_width_exp(_tile_width_exp),
00108       offset_bitmask((1 << _tile_width_exp) - 1),
00109       directory(_directory),
00110       tile_cache(_directory, _tile_width_exp, _persistent) {
00111 
00112       if(!file_exists(_directory)) create_directory(_directory);
00113 
00114     }
00115 
00116     /**
00117      * The destructor.
00118      */
00119     virtual ~StoragePolicy_Tile() {
00120       if(persistent == false) remove_directory(directory);
00121     }
00122 
00123 
00124     /**
00125      * Get the width / height of a single tile. The size is a power of two.
00126      */
00127 
00128     inline unsigned int get_tile_size() const {
00129       return (1 << tile_width_exp);
00130     }
00131 
00132 
00133     /**
00134      * Get the directory, where images are stored.
00135      */
00136     std::string get_directory() const { return directory; }
00137 
00138     /**
00139      * Check if the image is persistent.
00140      */
00141     bool is_persistent() const { return persistent; }
00142 
00143 
00144     inline typename PixelPolicy::pixel_type get_pixel(unsigned int x, unsigned int y) const;
00145 
00146     inline void set_pixel(unsigned int x, unsigned int y, typename PixelPolicy::pixel_type new_val);
00147 
00148     /**
00149      * Copy the raw data from an image tile that has its upper left corner at x,y into a buffer.
00150      */
00151     void raw_copy(void * dst_buf, unsigned int src_x, unsigned int src_y) const {
00152       MemoryMap_shptr mem = tile_cache.get_tile(src_x, src_y);
00153       mem->raw_copy(dst_buf);
00154     }
00155 
00156 
00157   };
00158 
00159   template<class PixelPolicy>
00160   inline typename PixelPolicy::pixel_type
00161   StoragePolicy_Tile<PixelPolicy>::get_pixel(unsigned int x,
00162                                              unsigned int y) const {
00163     MemoryMap_shptr mem = tile_cache.get_tile(x, y);
00164     return mem->get(x & offset_bitmask, y & offset_bitmask);
00165   }
00166 
00167   template<class PixelPolicy>
00168   inline void
00169   StoragePolicy_Tile<PixelPolicy>::set_pixel(unsigned int x, unsigned int y,
00170                                              typename PixelPolicy::pixel_type new_val) {
00171 
00172     MemoryMap_shptr mem = tile_cache.get_tile(x, y);
00173     mem->set(x & offset_bitmask, y & offset_bitmask, new_val);
00174   }
00175 
00176 
00177 
00178 
00179 
00180 }
00181 
00182 
00183 
00184 
00185 #endif