1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
#ifndef HPC_MATVEC_MATRIX2PIXBUF_H
#define HPC_MATVEC_MATRIX2PIXBUF_H

#include <gdk-pixbuf/gdk-pixbuf.h>
#include <hpc/aux/rgbcolor.h>
#include <hpc/matvec/gematrix.h>
#include <hpc/matvec/isgematrix.h>

namespace hpc { namespace matvec {

/*
   generate colorized pixmap from A:

      y
      ^
      |   A(0, A.numCols-1)    ...      A(A.numRows-1, A.numCols-1)
      |          .                                   .
      |          .                                   .
      |          .                                   .
      |        A(0, 0)         ...           A(A.numRows-1, 0)
      +---------------------------------------------------------------> x

   whereas the first index from 0 to A.numRows-1 is associated with the x axis
   and whereas the second index from 0 to A.numCols-1 is tied to the y axis

   the scale factor creates larger blocks of scale x scale pixels
*/
template <typename MA, typename Colorizer>
typename std::enable_if<IsGeMatrix<MA>::value,
         GdkPixbuf*>::type
create_pixbuf(MA& A, Colorizer colorizer, unsigned int scale = 1) {
   int width = A.numRows * scale;
   int height = A.numCols * scale;
   GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE,
      8, width, height);
   int n_channels = gdk_pixbuf_get_n_channels(pixbuf);
   int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
   guchar* pixels = gdk_pixbuf_get_pixels(pixbuf);
   if (!pixels) return nullptr;

   for (int i = 0; i < A.numCols; ++i) {
      for (int j = 0; j < A.numRows; ++j) {
         auto color = colorizer(A(i, j));
         auto rgbcolor = color.get_rgb();
         for (int scale_i = 0; scale_i < scale; ++scale_i) {
            for (int scale_j = 0; scale_j < scale; ++scale_j) {
               int i_ = height - 1 - (j * scale + scale_j);
               int j_ = i * scale + scale_i;
               assert(i_ >= 0 && i_ < height);
               assert(j_ >= 0 && j_ < width);
               guchar* pp = pixels + i_ * rowstride + j_ * n_channels;
               pp[0] = rgbcolor.red * 255;
               pp[1] = rgbcolor.green * 255;
               pp[2] = rgbcolor.blue * 255;
            }
         }
      }
   }
   return pixbuf;
}

} } // namespaces matvec, hpc

#endif