colormap.cpp

00001
00002 /**************************************************************************
00003  *  colormap.h - colormap interface
00004  *
00005  *  Created: Sat Mar 29 12:45:29 2008
00006  *  Copyright  2005-2008  Tim Niemueller  [www.niemueller.de]
00007  *
00008  ***************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023
00024 #include <fvutils/colormap/colormap.h>
00025
00026 #include <fvutils/color/color_object_map.h>
00027 #include <cstring>
00028 
00029 /** @class Colormap <fvutils/colormap/colormap.h>
00030  * Colormap interface.
00031  * This C++ pure virtual class describes the interface to a generic colormap. It is
00032  * currently tailored to the YUV colorspace.
00033  *
00034  * @author Tim Niemueller
00035  *
00036  *
00037  * @fn color_t Colormap::determine(unsigned int y, unsigned int u, unsigned int v) const = 0
00038  * Determine color class for given YUV value.
00039  * @param y Y value from YUV colorspace
00040  * @param u U value from YUV colorspace
00041  * @param v V value from YUV colorspace
00042  * @return color class for the given YUV color
00043  *
00044  * @fn void Colormap::set(unsigned int y, unsigned int u, unsigned int v, color_t c) = 0
00045  * Set color class for given YUV value.
00046  * @param y Y value from YUV colorspace
00047  * @param u U value from YUV colorspace
00048  * @param v V value from YUV colorspace
00049  * @param c class for the given YUV color
00050  *
00051  * @fn void Colormap::reset() = 0
00052  * Reset colormap.
00053  * Resets all values to return C_UNKNOWN for every query with determine().
00054  *
00055  * @fn void Colormap::set(unsigned char *buffer) = 0
00056  * Set to the given raw buffer.
00057  * @param buffer buffer to copy data from
00058  *
00059  * @fn size_t Colormap::size() = 0
00060  * Size in bytes of buffer returned by get_buffer().
00061  *
00062  * @fn unsigned char * Colormap::get_buffer() const = 0
00063  * Get the raw buffer of this colormap.
00064  * @return raw buffer
00065  *
00066  * @fn Colormap &  Colormap::operator+=(const Colormap & cmlt) = 0
00067  * Adds the given colormap to this colormap.
00068  * This operator takes the given colormap and compares it to this colormap. If this colormap
00069  * has C_OTHER or C_BACKGROUND the value is compied from the other LUT, otherwise the
00070  * value is kept as is.
00071  * @param cmlt other colormap to add
00072  * @return reference to this
00073  *
00074  * @fn Colormap & Colormap::operator+=(const char *filename) = 0
00075  * Convenience method for the method above.
00076  * This adds the colormap as in the above method but instead of an instantiated colormap
00077  * it takes the path to a colormap file which is loaded and added.
00078  * @param filename file name of colormap to add
00079  * @return reference to this
00080  *
00081  * @fn unsigned int Colormap::width() const = 0
00082  * Get width of colormap.
00083  * @return colormap width, meaning depends on actual colormap implementation
00084  *
00085  * @fn unsigned int Colormap::height() const = 0
00086  * Get height of colormap.
00087  * @return colormap height, meaning depends on actual colormap implementation
00088  *
00089  * @fn unsigned int Colormap::depth() const = 0
00090  * Get depth of colormap.
00091  * @return colormap depth, meaning depends on actual colormap implementation
00092  *
00093  * @fn unsigned int Colormap::deepness() const = 0
00094  * Get deepness of colormap.
00095  * The deepness is the maximum value of depth().
00096  * @return colormap deepness, meaning depends on actual colormap implementation
00097  *
00098  * @fn std::list<ColormapFileBlock *>  Colormap::get_blocks() = 0
00099  * Get file blocks for this colormap.
00100  * @return list of colormap blocks for this colormap.
00101  *
00102  */
00103 
00104 /** Virtual empty destructor. */
00105 Colormap::~Colormap()
00106 {
00107 }
00108 
00109 /** Create image from LUT.
00110  * Create image from LUT, useful for debugging and analysing.
00111  * This method produces a representation of the given level
00112  * (Y range with 0 <= level < depth) for visual inspection of the colormap.
00113  * The dimensions of the resulting image are 512x512 pixels. It uses standard strong
00114  * colors for the different standard color classes. C_UNKNOWN is grey, C_BACKGROUND
00115  * is black (like C_BLACK).
00116  * If the standard method does not suit your needs you can override this method.
00117  * @param yuv422_planar_buffer contains the image upon return, must be initialized
00118  * with the appropriate memory size before calling, dimensions are 512x512 pixels.
00119  * @param level the level to draw, it's a range in the Y direction and is in the
00120  * range 0 <= level < depth.
00121  */
00122 void
00123 Colormap::to_image(unsigned char *yuv422_planar_buffer, unsigned int level)
00124 {
00125   unsigned int lwidth  = width();
00126   unsigned int lheight = height();
00127
00128   unsigned char *yp = yuv422_planar_buffer;
00129   unsigned char *up = YUV422_PLANAR_U_PLANE(yuv422_planar_buffer, lwidth * 2, lheight * 2);
00130   unsigned char *vp = YUV422_PLANAR_V_PLANE(yuv422_planar_buffer, lwidth * 2, lheight * 2);
00131
00132   unsigned int y = level * deepness() / depth();
00133
00134   YUV_t c;
00135   for (unsigned int v = lwidth; v > 0 ; --v) {
00136     unsigned int v_index = (v - 1) * deepness() / lwidth;
00137     for (unsigned int u = 0; u < lheight; ++u) {
00138       unsigned int u_index = u * deepness() / lheight;
00139       c = ColorObjectMap::get_color(determine(y, u_index, v_index));
00140
00141       *yp++ = c.Y;
00142       *yp++ = c.Y;
00143       *up++ = c.U;
00144       *vp++ = c.V;
00145     }
00146     // Double line
00147     memcpy(yp, (yp - lwidth * 2), lwidth *2);
00148     yp += lwidth * 2;
00149     memcpy(up, (up - lwidth), lwidth);
00150     memcpy(vp, (vp - lwidth), lwidth);
00151     up += lwidth;
00152     vp += lwidth;
00153   }
00154 }