C++ Bitmap Library  release
Classes | Macros | Enumerations | Functions | Variables
bitmap_image.hpp File Reference
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <iterator>
#include <limits>
#include <string>
#include <vector>
Include dependency graph for bitmap_image.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  bitmap_image
 
struct  rgb_t
 
class  image_drawer
 
class  cartesian_canvas
 
class  response_image< T >
 

Macros

#define round(d)   std::floor(d + 0.5)
 

Enumerations

enum  palette_name {
  e_red, e_scarlet, e_vermilion, e_tangelo,
  e_orange, e_gamboge, e_amber, e_gold,
  e_yellow, e_apple_green, e_lime_green, e_spring_bud,
  e_chartreuse_green, e_pistachio, e_harlequin, e_sap_green,
  e_green, e_emerald_green, e_malachite_green, e_sea_green,
  e_spring_green, e_aquamarine, e_turquoise, e_opal,
  e_cyan, e_arctic_blue, e_cerulean, e_cornflower_blue,
  e_azure, e_cobalt_blue, e_sapphire_blue, e_phthalo_blue,
  e_blue, e_persian_blue, e_indigo, e_blue_violet,
  e_violet, e_purple, e_mulberry, e_heliotrope,
  e_magenta, e_orchid, e_fuchsia, e_cerise,
  e_rose, e_raspberry, e_crimson, e_amaranth,
  e_white, e_black
}
 

Functions

bool operator== (const rgb_t &c0, const rgb_t &c1)
 
bool operator!= (const rgb_t &c0, const rgb_t &c1)
 
std::size_t hamming_distance (const rgb_t &c0, const rgb_t &c1)
 
rgb_t make_colour (const unsigned int &red, const unsigned int &green, const unsigned int &blue)
 
template<typename OutputIterator >
void generate_colours (const std::size_t &steps, const rgb_t c0, const rgb_t &c1, OutputIterator out)
 
template<typename ResponseImage , typename Palette >
std::size_t convert_rsp_to_image (const ResponseImage &resp_image, const Palette &palette, bitmap_image &image)
 
void rgb_to_ycbcr (const unsigned int &length, double *red, double *green, double *blue, double *y, double *cb, double *cr)
 
void ycbcr_to_rgb (const unsigned int &length, double *y, double *cb, double *cr, double *red, double *green, double *blue)
 
void subsample (const unsigned int &width, const unsigned int &height, const double *source, unsigned int &w, unsigned int &h, double *&dest)
 
void upsample (const unsigned int &width, const unsigned int &height, const double *source, unsigned int &w, unsigned int &h, double *&dest)
 
void checkered_pattern (const unsigned int x_width, const unsigned int y_width, const unsigned char value, const bitmap_image::color_plane color, bitmap_image &image)
 
void checkered_pattern (const unsigned int x_width, const unsigned int y_width, const unsigned char red, const unsigned char green, const unsigned char blue, bitmap_image &image)
 
void plasma (bitmap_image &image, const double &x, const double &y, const double &width, const double &height, const double &c1, const double &c2, const double &c3, const double &c4, const double &roughness=3.0, const rgb_t colormap[]=0)
 
void plasma (bitmap_image &image, const double &c1, const double &c2, const double &c3, const double &c4, const double &roughness=3.0, const rgb_t colormap[]=0)
 
double psnr_region (const unsigned int &x, const unsigned int &y, const unsigned int &width, const unsigned int &height, const bitmap_image &image1, const bitmap_image &image2)
 
void hierarchical_psnr_r (const double &x, const double &y, const double &width, const double &height, const bitmap_image &image1, bitmap_image &image2, const double &threshold, const rgb_t colormap[])
 
void hierarchical_psnr (bitmap_image &image1, bitmap_image &image2, const double threshold, const rgb_t colormap[])
 
rgb_t convert_wave_length_nm_to_rgb (const double wave_length_nm)
 
double weighted_distance (const unsigned char r0, const unsigned char g0, const unsigned char b0, const unsigned char r1, const unsigned char g1, const unsigned char b1)
 
double weighted_distance (const rgb_t c0, const rgb_t c1)
 
template<typename Iterator >
rgb_t find_nearest_color (const rgb_t &c, const Iterator begin, const Iterator end)
 
template<template< typename, typename > class Sequence, typename Allocator >
rgb_t find_nearest_color (const rgb_t &c, const Sequence< rgb_t, Allocator > &seq)
 
template<std::size_t N>
rgb_t find_nearest_color (const rgb_t &c, const rgb_t(&colors)[N])
 
double find_nearest_wave_length (const rgb_t &c, const double increment=0.001)
 
void sobel_operator (const bitmap_image &src_image, bitmap_image &dst_image, const double threshold=0.0)
 

Variables

const rgb_t palette_colormap []
 
const rgb_t autumn_colormap [1000]
 
const rgb_t copper_colormap [1000]
 
const rgb_t gray_colormap [1000]
 
const rgb_t hot_colormap [1000]
 
const rgb_t hsv_colormap [1000]
 
const rgb_t jet_colormap [1000]
 
const rgb_t prism_colormap [1000]
 
const rgb_t vga_colormap [1000]
 
const rgb_t yarg_colormap [1000]
 

Macro Definition Documentation

◆ round

#define round (   d)    std::floor(d + 0.5)

Enumeration Type Documentation

◆ palette_name

Enumerator
e_red 
e_scarlet 
e_vermilion 
e_tangelo 
e_orange 
e_gamboge 
e_amber 
e_gold 
e_yellow 
e_apple_green 
e_lime_green 
e_spring_bud 
e_chartreuse_green 
e_pistachio 
e_harlequin 
e_sap_green 
e_green 
e_emerald_green 
e_malachite_green 
e_sea_green 
e_spring_green 
e_aquamarine 
e_turquoise 
e_opal 
e_cyan 
e_arctic_blue 
e_cerulean 
e_cornflower_blue 
e_azure 
e_cobalt_blue 
e_sapphire_blue 
e_phthalo_blue 
e_blue 
e_persian_blue 
e_indigo 
e_blue_violet 
e_violet 
e_purple 
e_mulberry 
e_heliotrope 
e_magenta 
e_orchid 
e_fuchsia 
e_cerise 
e_rose 
e_raspberry 
e_crimson 
e_amaranth 
e_white 
e_black 

Definition at line 3115 of file bitmap_image.hpp.

3116 {
3127 };

Function Documentation

◆ checkered_pattern() [1/2]

void checkered_pattern ( const unsigned int  x_width,
const unsigned int  y_width,
const unsigned char  value,
const bitmap_image::color_plane  color,
bitmap_image image 
)
inline

Definition at line 1847 of file bitmap_image.hpp.

References bitmap_image::bytes_per_pixel(), bitmap_image::height(), bitmap_image::offset(), bitmap_image::row(), and bitmap_image::width().

Referenced by test14().

1852 {
1853  if (
1854  (x_width >= image.width ()) ||
1855  (y_width >= image.height())
1856  )
1857  {
1858  return;
1859  }
1860 
1861  bool setter_x = false;
1862  bool setter_y = true;
1863 
1864  const unsigned int color_plane_offset = image.offset(color);
1865  const unsigned int height = image.height();
1866  const unsigned int width = image.width();
1867 
1868  for (unsigned int y = 0; y < height; ++y)
1869  {
1870  if (0 == (y % y_width))
1871  {
1872  setter_y = !setter_y;
1873  }
1874 
1875  unsigned char* row = image.row(y) + color_plane_offset;
1876 
1877  for (unsigned int x = 0; x < width; ++x, row += image.bytes_per_pixel())
1878  {
1879  if (0 == (x % x_width))
1880  {
1881  setter_x = !setter_x;
1882  }
1883 
1884  if (setter_x ^ setter_y)
1885  {
1886  *row = value;
1887  }
1888  }
1889  }
1890 }
unsigned int height() const
unsigned int width() const
unsigned char * row(unsigned int row_index) const
unsigned int bytes_per_pixel() const
unsigned int offset(const color_plane color)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ checkered_pattern() [2/2]

void checkered_pattern ( const unsigned int  x_width,
const unsigned int  y_width,
const unsigned char  red,
const unsigned char  green,
const unsigned char  blue,
bitmap_image image 
)
inline

Definition at line 1892 of file bitmap_image.hpp.

References bitmap_image::bytes_per_pixel(), bitmap_image::height(), bitmap_image::row(), and bitmap_image::width().

1898 {
1899  if (
1900  (x_width >= image.width ()) ||
1901  (y_width >= image.height())
1902  )
1903  {
1904  return;
1905  }
1906 
1907  bool setter_x = false;
1908  bool setter_y = true;
1909 
1910  const unsigned int height = image.height();
1911  const unsigned int width = image.width();
1912 
1913  for (unsigned int y = 0; y < height; ++y)
1914  {
1915  if (0 == (y % y_width))
1916  {
1917  setter_y = !setter_y;
1918  }
1919 
1920  unsigned char* row = image.row(y);
1921 
1922  for (unsigned int x = 0; x < width; ++x, row += image.bytes_per_pixel())
1923  {
1924  if (0 == (x % x_width))
1925  {
1926  setter_x = !setter_x;
1927  }
1928 
1929  if (setter_x ^ setter_y)
1930  {
1931  *(row + 0) = blue;
1932  *(row + 1) = green;
1933  *(row + 2) = red;
1934  }
1935  }
1936  }
1937 }
unsigned int height() const
unsigned int width() const
unsigned char * row(unsigned int row_index) const
unsigned int bytes_per_pixel() const
Here is the call graph for this function:

◆ convert_rsp_to_image()

template<typename ResponseImage , typename Palette >
std::size_t convert_rsp_to_image ( const ResponseImage &  resp_image,
const Palette &  palette,
bitmap_image image 
)
inline

Definition at line 1673 of file bitmap_image.hpp.

References bitmap_image::height(), bitmap_image::set_pixel(), and bitmap_image::width().

1674 {
1675  if (
1676  (resp_image.width () > image.width ()) ||
1677  (resp_image.height() > image.height())
1678  )
1679  return 0;
1680 
1681  for (std::size_t y = 0; y < resp_image.height(); ++y)
1682  {
1683  for (std::size_t x = 0; x < resp_image.width(); ++x)
1684  {
1685  const double v = resp_image(x,y);
1686 
1687  unsigned int index = static_cast<unsigned int>((v < 0) ? 0 : v > (palette.size()) ? (palette.size() - 1) : v);
1688 
1689  image.set_pixel(x,y,palette[index]);
1690  }
1691  }
1692 
1693  return (resp_image.width() * resp_image.height());
1694 }
void set_pixel(const unsigned int x, const unsigned int y, const unsigned char red, const unsigned char green, const unsigned char blue)
unsigned int height() const
unsigned int width() const
Here is the call graph for this function:

◆ convert_wave_length_nm_to_rgb()

rgb_t convert_wave_length_nm_to_rgb ( const double  wave_length_nm)
inline

Definition at line 2831 of file bitmap_image.hpp.

References rgb_t::blue, rgb_t::green, rgb_t::red, and round.

Referenced by find_nearest_wave_length().

2832 {
2833  // Credits: Dan Bruton http://www.physics.sfasu.edu/astro/color.html
2834  double red = 0.0;
2835  double green = 0.0;
2836  double blue = 0.0;
2837 
2838  if ((380.0 <= wave_length_nm) && (wave_length_nm <= 439.0))
2839  {
2840  red = -(wave_length_nm - 440.0) / (440.0 - 380.0);
2841  green = 0.0;
2842  blue = 1.0;
2843  }
2844  else if ((440.0 <= wave_length_nm) && (wave_length_nm <= 489.0))
2845  {
2846  red = 0.0;
2847  green = (wave_length_nm - 440.0) / (490.0 - 440.0);
2848  blue = 1.0;
2849  }
2850  else if ((490.0 <= wave_length_nm) && (wave_length_nm <= 509.0))
2851  {
2852  red = 0.0;
2853  green = 1.0;
2854  blue = -(wave_length_nm - 510.0) / (510.0 - 490.0);
2855  }
2856  else if ((510.0 <= wave_length_nm) && (wave_length_nm <= 579.0))
2857  {
2858  red = (wave_length_nm - 510.0) / (580.0 - 510.0);
2859  green = 1.0;
2860  blue = 0.0;
2861  }
2862  else if ((580.0 <= wave_length_nm) && (wave_length_nm <= 644.0))
2863  {
2864  red = 1.0;
2865  green = -(wave_length_nm - 645.0) / (645.0 - 580.0);
2866  blue = 0.0;
2867  }
2868  else if ((645.0 <= wave_length_nm) && (wave_length_nm <= 780.0))
2869  {
2870  red = 1.0;
2871  green = 0.0;
2872  blue = 0.0;
2873  }
2874 
2875  double factor = 0.0;
2876 
2877  if ((380.0 <= wave_length_nm) && (wave_length_nm <= 419.0))
2878  factor = 0.3 + 0.7 * (wave_length_nm - 380.0) / (420.0 - 380.0);
2879  else if ((420.0 <= wave_length_nm) && (wave_length_nm <= 700.0))
2880  factor = 1.0;
2881  else if ((701.0 <= wave_length_nm) && (wave_length_nm <= 780.0))
2882  factor = 0.3 + 0.7 * (780.0 - wave_length_nm) / (780.0 - 700.0);
2883  else
2884  factor = 0.0;
2885 
2886  rgb_t result;
2887 
2888  const double gamma = 0.8;
2889  const double intensity_max = 255.0;
2890 
2891  #define round(d) std::floor(d + 0.5)
2892 
2893  result.red = static_cast<unsigned char>((red == 0.0) ? red : round(intensity_max * std::pow(red * factor, gamma)));
2894  result.green = static_cast<unsigned char>((green == 0.0) ? green : round(intensity_max * std::pow(green * factor, gamma)));
2895  result.blue = static_cast<unsigned char>((blue == 0.0) ? blue : round(intensity_max * std::pow(blue * factor, gamma)));
2896 
2897  #undef round
2898 
2899  return result;
2900 }
unsigned char red
unsigned char green
unsigned char blue
#define round(d)
Here is the caller graph for this function:

◆ find_nearest_color() [1/3]

template<typename Iterator >
rgb_t find_nearest_color ( const rgb_t c,
const Iterator  begin,
const Iterator  end 
)
inline

Definition at line 2919 of file bitmap_image.hpp.

References weighted_distance().

Referenced by find_nearest_color().

2920 {
2921  if (0 == std::distance(begin,end))
2922  return c;
2923 
2924  double min_d = std::numeric_limits<double>::max();
2925  rgb_t result = *begin;
2926 
2927  for (Iterator itr = begin; itr != end; ++itr)
2928  {
2929  if (c == (*itr))
2930  {
2931  return (*itr);
2932  }
2933 
2934  double curr_d = weighted_distance(c,*itr);
2935 
2936  if (curr_d < min_d)
2937  {
2938  min_d = curr_d;
2939  result = *itr;
2940  }
2941  }
2942 
2943  return result;
2944 }
double weighted_distance(const unsigned char r0, const unsigned char g0, const unsigned char b0, const unsigned char r1, const unsigned char g1, const unsigned char b1)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_nearest_color() [2/3]

template<template< typename, typename > class Sequence, typename Allocator >
rgb_t find_nearest_color ( const rgb_t c,
const Sequence< rgb_t, Allocator > &  seq 
)
inline

Definition at line 2948 of file bitmap_image.hpp.

References find_nearest_color().

2949 {
2950  return find_nearest_color(c, seq.begin(),seq.end());
2951 }
rgb_t find_nearest_color(const rgb_t &c, const Iterator begin, const Iterator end)
Here is the call graph for this function:

◆ find_nearest_color() [3/3]

template<std::size_t N>
rgb_t find_nearest_color ( const rgb_t c,
const rgb_t(&)  colors[N] 
)
inline

Definition at line 2954 of file bitmap_image.hpp.

References find_nearest_color().

2955 {
2956  return find_nearest_color(c, colors, colors + N);
2957 }
rgb_t find_nearest_color(const rgb_t &c, const Iterator begin, const Iterator end)
Here is the call graph for this function:

◆ find_nearest_wave_length()

double find_nearest_wave_length ( const rgb_t c,
const double  increment = 0.001 
)
inline

Definition at line 2959 of file bitmap_image.hpp.

References convert_wave_length_nm_to_rgb(), and weighted_distance().

2960 {
2961  const double max_wave_length = 800.0; //800nm
2962 
2963  double min_wave_length = 0.0;
2964  double min_d = std::numeric_limits<double>::max();
2965 
2966  for (double i = 0.0; i < max_wave_length; i += increment)
2967  {
2968  rgb_t curr_rgb = convert_wave_length_nm_to_rgb(i);
2969 
2970  if (c == curr_rgb)
2971  {
2972  return i;
2973  }
2974 
2975  const double curr_d = weighted_distance(c, curr_rgb);
2976 
2977  if (curr_d <= min_d)
2978  {
2979  min_wave_length = i;
2980  min_d = curr_d;
2981  }
2982  }
2983 
2984  return min_wave_length;
2985 }
rgb_t convert_wave_length_nm_to_rgb(const double wave_length_nm)
double weighted_distance(const unsigned char r0, const unsigned char g0, const unsigned char b0, const unsigned char r1, const unsigned char g1, const unsigned char b1)
Here is the call graph for this function:

◆ generate_colours()

template<typename OutputIterator >
void generate_colours ( const std::size_t &  steps,
const rgb_t  c0,
const rgb_t c1,
OutputIterator  out 
)
inline

Definition at line 1654 of file bitmap_image.hpp.

References rgb_t::blue, rgb_t::green, and rgb_t::red.

1655 {
1656  double dr = ((double)c1.red - (double)c0.red ) / steps;
1657  double dg = ((double)c1.green - (double)c0.green ) / steps;
1658  double db = ((double)c1.blue - (double)c0.blue ) / steps;
1659 
1660  for (std::size_t i = 0; i < steps; ++i)
1661  {
1662  rgb_t c;
1663 
1664  c.red = static_cast<unsigned char>(c0.red + (i * dr));
1665  c.green = static_cast<unsigned char>(c0.green + (i * dg));
1666  c.blue = static_cast<unsigned char>(c0.blue + (i * db));
1667 
1668  *(out++) = c;
1669  }
1670 }
unsigned char red
unsigned char green
unsigned char blue

◆ hamming_distance()

std::size_t hamming_distance ( const rgb_t c0,
const rgb_t c1 
)
inline

Definition at line 1631 of file bitmap_image.hpp.

References rgb_t::blue, rgb_t::green, and rgb_t::red.

1632 {
1633  std::size_t result = 0;
1634 
1635  if (c0.red != c1 .red) ++result;
1636  if (c0.green != c1.green) ++result;
1637  if (c0.blue != c1 .blue) ++result;
1638 
1639  return result;
1640 }
unsigned char red
unsigned char green
unsigned char blue

◆ hierarchical_psnr()

void hierarchical_psnr ( bitmap_image image1,
bitmap_image image2,
const double  threshold,
const rgb_t  colormap[] 
)
inline

Definition at line 2076 of file bitmap_image.hpp.

References bitmap_image::height(), hierarchical_psnr_r(), bitmap_image::psnr(), psnr_region(), and bitmap_image::width().

2077 {
2078  if (
2079  (image1.width() != image2.width ()) ||
2080  (image1.height() != image2.height())
2081  )
2082  {
2083  return;
2084  }
2085 
2086  double psnr = psnr_region(0,0,image1.width(),image1.height(),image1,image2);
2087 
2088  if (psnr < threshold)
2089  {
2090  hierarchical_psnr_r(0, 0, image1.width(), image1.height(),
2091  image1, image2,
2092  threshold, colormap);
2093  }
2094 }
unsigned int height() const
unsigned int width() const
double psnr_region(const unsigned int &x, const unsigned int &y, const unsigned int &width, const unsigned int &height, const bitmap_image &image1, const bitmap_image &image2)
void hierarchical_psnr_r(const double &x, const double &y, const double &width, const double &height, const bitmap_image &image1, bitmap_image &image2, const double &threshold, const rgb_t colormap[])
Here is the call graph for this function:

◆ hierarchical_psnr_r()

void hierarchical_psnr_r ( const double &  x,
const double &  y,
const double &  width,
const double &  height,
const bitmap_image image1,
bitmap_image image2,
const double &  threshold,
const rgb_t  colormap[] 
)
inline

Definition at line 2034 of file bitmap_image.hpp.

References rgb_t::blue, rgb_t::green, bitmap_image::psnr(), psnr_region(), rgb_t::red, and bitmap_image::set_region().

Referenced by hierarchical_psnr().

2040 {
2041  if ((width <= 4.0) || (height <= 4.0))
2042  {
2043  double psnr = psnr_region(
2044  static_cast<unsigned int>(x),
2045  static_cast<unsigned int>(y),
2046  static_cast<unsigned int>(width),
2047  static_cast<unsigned int>(height),
2048  image1, image2
2049  );
2050 
2051  if (psnr < threshold)
2052  {
2053  rgb_t c = colormap[static_cast<unsigned int>(1000.0 * (1.0 - (psnr / threshold)))];
2054 
2055  image2.set_region(
2056  static_cast<unsigned int>(x),
2057  static_cast<unsigned int>(y),
2058  static_cast<unsigned int>(width + 1),
2059  static_cast<unsigned int>(height + 1),
2060  c.red, c.green, c.blue
2061  );
2062  }
2063  }
2064  else
2065  {
2066  double half_width = ( width / 2.0);
2067  double half_height = (height / 2.0);
2068 
2069  hierarchical_psnr_r(x , y , half_width, half_height, image1, image2, threshold, colormap);
2070  hierarchical_psnr_r(x + half_width, y , half_width, half_height, image1, image2, threshold, colormap);
2071  hierarchical_psnr_r(x + half_width, y + half_height, half_width, half_height, image1, image2, threshold, colormap);
2072  hierarchical_psnr_r(x , y + half_height, half_width, half_height, image1, image2, threshold, colormap);
2073  }
2074 }
unsigned char red
unsigned char green
double psnr_region(const unsigned int &x, const unsigned int &y, const unsigned int &width, const unsigned int &height, const bitmap_image &image1, const bitmap_image &image2)
unsigned char blue
void hierarchical_psnr_r(const double &x, const double &y, const double &width, const double &height, const bitmap_image &image1, bitmap_image &image2, const double &threshold, const rgb_t colormap[])
bool set_region(const unsigned int &x, const unsigned int &y, const unsigned int &width, const unsigned int &height, const unsigned char &value)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_colour()

rgb_t make_colour ( const unsigned int &  red,
const unsigned int &  green,
const unsigned int &  blue 
)
inline

Definition at line 1642 of file bitmap_image.hpp.

References rgb_t::blue, rgb_t::green, and rgb_t::red.

1643 {
1644  rgb_t result;
1645 
1646  result.red = static_cast<unsigned char>(red );
1647  result.green = static_cast<unsigned char>(green);
1648  result.blue = static_cast<unsigned char>(blue );
1649 
1650  return result;
1651 }
unsigned char red
unsigned char green
unsigned char blue

◆ operator!=()

bool operator!= ( const rgb_t c0,
const rgb_t c1 
)
inline

Definition at line 1624 of file bitmap_image.hpp.

References rgb_t::blue, rgb_t::green, and rgb_t::red.

1625 {
1626  return (c0.red != c1 .red) ||
1627  (c0.green != c1.green) ||
1628  (c0.blue != c1 .blue);
1629 }
unsigned char red
unsigned char green
unsigned char blue

◆ operator==()

bool operator== ( const rgb_t c0,
const rgb_t c1 
)
inline

Definition at line 1617 of file bitmap_image.hpp.

References rgb_t::blue, rgb_t::green, and rgb_t::red.

1618 {
1619  return (c0.red == c1 .red) &&
1620  (c0.green == c1.green) &&
1621  (c0.blue == c1 .blue);
1622 }
unsigned char red
unsigned char green
unsigned char blue

◆ plasma() [1/2]

void plasma ( bitmap_image image,
const double &  x,
const double &  y,
const double &  width,
const double &  height,
const double &  c1,
const double &  c2,
const double &  c3,
const double &  c4,
const double &  roughness = 3.0,
const rgb_t  colormap[] = 0 
)
inline

Definition at line 1939 of file bitmap_image.hpp.

References bitmap_image::height(), bitmap_image::set_pixel(), and bitmap_image::width().

Referenced by plasma(), test15(), test16(), and test17().

1946 {
1947  // Note: c1,c2,c3,c4 -> [0.0,1.0]
1948 
1949  double half_width = ( width / 2.0);
1950  double half_height = (height / 2.0);
1951 
1952  if ((width >= 1.0) || (height >= 1.0))
1953  {
1954  double corner1 = (c1 + c2) / 2.0;
1955  double corner2 = (c2 + c3) / 2.0;
1956  double corner3 = (c3 + c4) / 2.0;
1957  double corner4 = (c4 + c1) / 2.0;
1958  double center = (c1 + c2 + c3 + c4) / 4.0 +
1959  ((1.0 * ::rand() /(1.0 * RAND_MAX)) - 0.5) * // should use a better rng
1960  ((1.0 * half_width + half_height) / (image.width() + image.height()) * roughness);
1961 
1962  center = std::min<double>(std::max<double>(0.0,center),1.0);
1963 
1964  plasma(image, x, y, half_width, half_height, c1, corner1, center, corner4,roughness,colormap);
1965  plasma(image, x + half_width, y, half_width, half_height, corner1, c2, corner2, center,roughness,colormap);
1966  plasma(image, x + half_width, y + half_height, half_width, half_height, center, corner2, c3, corner3,roughness,colormap);
1967  plasma(image, x, y + half_height, half_width, half_height, corner4, center, corner3, c4,roughness,colormap);
1968  }
1969  else
1970  {
1971  rgb_t color = colormap[static_cast<unsigned int>(1000.0 * ((c1 + c2 + c3 + c4) / 4.0)) % 1000];
1972 
1973  image.set_pixel(static_cast<unsigned int>(x),static_cast<unsigned int>(y),color);
1974  }
1975 }
void set_pixel(const unsigned int x, const unsigned int y, const unsigned char red, const unsigned char green, const unsigned char blue)
unsigned int height() const
unsigned int width() const
void plasma(bitmap_image &image, const double &x, const double &y, const double &width, const double &height, const double &c1, const double &c2, const double &c3, const double &c4, const double &roughness=3.0, const rgb_t colormap[]=0)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ plasma() [2/2]

void plasma ( bitmap_image image,
const double &  c1,
const double &  c2,
const double &  c3,
const double &  c4,
const double &  roughness = 3.0,
const rgb_t  colormap[] = 0 
)
inline

Definition at line 1977 of file bitmap_image.hpp.

References bitmap_image::height(), plasma(), and bitmap_image::width().

1982 {
1983  plasma
1984  (
1985  image, 0, 0, image.width(), image.height(),
1986  c1, c2, c3, c4,
1987  roughness, colormap
1988  );
1989 }
unsigned int height() const
unsigned int width() const
void plasma(bitmap_image &image, const double &x, const double &y, const double &width, const double &height, const double &c1, const double &c2, const double &c3, const double &c4, const double &roughness=3.0, const rgb_t colormap[]=0)
Here is the call graph for this function:

◆ psnr_region()

double psnr_region ( const unsigned int &  x,
const unsigned int &  y,
const unsigned int &  width,
const unsigned int &  height,
const bitmap_image image1,
const bitmap_image image2 
)
inline

Definition at line 1991 of file bitmap_image.hpp.

References bitmap_image::bytes_per_pixel(), bitmap_image::height(), bitmap_image::row(), and bitmap_image::width().

Referenced by hierarchical_psnr(), and hierarchical_psnr_r().

1994 {
1995  if (
1996  (image1.width() != image2.width ()) ||
1997  (image1.height() != image2.height())
1998  )
1999  {
2000  return 0.0;
2001  }
2002 
2003  if ((x + width ) > image1.width() ) { return 0.0; }
2004  if ((y + height) > image1.height()) { return 0.0; }
2005 
2006  double mse = 0.0;
2007 
2008  for (unsigned int r = 0; r < height; ++r)
2009  {
2010  const unsigned char* itr1 = image1.row(r + y) + x * image1.bytes_per_pixel();
2011  const unsigned char* itr1_end = itr1 + (width * image1.bytes_per_pixel());
2012  const unsigned char* itr2 = image2.row(r + y) + x * image2.bytes_per_pixel();
2013 
2014  while (itr1 != itr1_end)
2015  {
2016  double v = (static_cast<double>(*itr1) - static_cast<double>(*itr2));
2017  mse += v * v;
2018  ++itr1;
2019  ++itr2;
2020  }
2021  }
2022 
2023  if (mse <= 0.0000001)
2024  {
2025  return 1000000.0;
2026  }
2027  else
2028  {
2029  mse /= (3.0 * width * height);
2030  return 20.0 * std::log10(255.0 / std::sqrt(mse));
2031  }
2032 }
unsigned int height() const
unsigned int width() const
unsigned char * row(unsigned int row_index) const
unsigned int bytes_per_pixel() const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rgb_to_ycbcr()

void rgb_to_ycbcr ( const unsigned int &  length,
double *  red,
double *  green,
double *  blue,
double *  y,
double *  cb,
double *  cr 
)
inline

Definition at line 1696 of file bitmap_image.hpp.

1698 {
1699  unsigned int i = 0;
1700 
1701  while (i < length)
1702  {
1703  ( *y) = 16.0 + ( 65.481 * (*red) + 128.553 * (*green) + 24.966 * (*blue));
1704  (*cb) = 128.0 + ( -37.797 * (*red) + -74.203 * (*green) + 112.000 * (*blue));
1705  (*cr) = 128.0 + ( 112.000 * (*red) + -93.786 * (*green) - 18.214 * (*blue));
1706 
1707  ++i;
1708  ++red; ++green; ++blue;
1709  ++y; ++cb; ++cr;
1710  }
1711 }

◆ sobel_operator()

void sobel_operator ( const bitmap_image src_image,
bitmap_image dst_image,
const double  threshold = 0.0 
)
inline

Definition at line 3069 of file bitmap_image.hpp.

References bitmap_image::export_gray_scale_response_image(), bitmap_image::height(), response_image< T >::height(), bitmap_image::import_gray_scale_clamped(), response_image< T >::row(), bitmap_image::setwidth_height(), bitmap_image::width(), and response_image< T >::width().

3072 {
3073  typedef double T;
3074 
3075  response_image<T> im0(src_image.width(), src_image.height(), 0.0);
3076  response_image<T> im1(src_image.width(), src_image.height(), 0.0);
3077 
3078  src_image.export_gray_scale_response_image(&im0(0,0));
3079 
3080  for (std::size_t y = 1; y < im0.height() - 1; ++y)
3081  {
3082  const T* itr0 = im0.row(y - 1);
3083  const T* itr1 = im0.row(y );
3084  const T* itr2 = im0.row(y + 1);
3085  T* out = im1.row(y ) + 1;
3086 
3087  for (std::size_t x = 1; x < im0.width() - 1; ++x)
3088  {
3089  const T c0 = *(itr0 + x - 1); const T c1 = *(itr0 + x); const T c2 = *(itr0 + x + 1);
3090  const T c3 = *(itr1 + x - 1); /*const T c4 = *(itr1 + x);*/ const T c5 = *(itr1 + x + 1);
3091  const T c6 = *(itr2 + x - 1); const T c7 = *(itr2 + x); const T c8 = *(itr2 + x + 1);
3092 
3093  const T gx = (2.0 * (c5 - c3)) + (c2 - c0) + (c8 - c6);
3094  const T gy = (2.0 * (c1 - c7)) + (c0 - c6) + (c2 - c8);
3095 
3096  *(out++) = std::sqrt((gx * gx) + (gy * gy));
3097  }
3098  }
3099 
3100  if (threshold > 0.0)
3101  {
3102  const T* end = im1.row(0) + (im1.width() * im1.height());
3103 
3104  for (T* itr = im1.row(0); itr != end; ++itr)
3105  {
3106  T& v = *itr;
3107  if (v <= threshold) v = 0;
3108  }
3109  }
3110 
3111  dst_image.setwidth_height(im1.width(), im1.height());
3112  dst_image.import_gray_scale_clamped(&im1(0,0));
3113 }
unsigned int height() const
unsigned int width() const
void export_gray_scale_response_image(double *response_image) const
void import_gray_scale_clamped(double *gray)
void setwidth_height(const unsigned int width, const unsigned int height, const bool clear=false)
Here is the call graph for this function:

◆ subsample()

void subsample ( const unsigned int &  width,
const unsigned int &  height,
const double *  source,
unsigned int &  w,
unsigned int &  h,
double *&  dest 
)
inline

Definition at line 1734 of file bitmap_image.hpp.

References bitmap_image::width().

1740 {
1741  /* Single channel. */
1742 
1743  w = 0;
1744  h = 0;
1745 
1746  bool odd_width = false;
1747  bool odd_height = false;
1748 
1749  if (0 == (width % 2))
1750  w = width / 2;
1751  else
1752  {
1753  w = 1 + (width / 2);
1754  odd_width = true;
1755  }
1756 
1757  if (0 == (height % 2))
1758  h = height / 2;
1759  else
1760  {
1761  h = 1 + (height / 2);
1762  odd_height = true;
1763  }
1764 
1765  unsigned int horizontal_upper = (odd_width) ? w - 1 : w;
1766  unsigned int vertical_upper = (odd_height) ? h - 1 : h;
1767 
1768  dest = new double[w * h];
1769 
1770  double* s_itr = dest;
1771  const double* itr1 = source;
1772  const double* itr2 = source + width;
1773 
1774  for (unsigned int j = 0; j < vertical_upper; ++j)
1775  {
1776  for (unsigned int i = 0; i < horizontal_upper; ++i, ++s_itr)
1777  {
1778  (*s_itr) = *(itr1++);
1779  (*s_itr) += *(itr1++);
1780  (*s_itr) += *(itr2++);
1781  (*s_itr) += *(itr2++);
1782  (*s_itr) /= 4.0;
1783  }
1784 
1785  if (odd_width)
1786  {
1787  (*(s_itr++)) = ((*itr1++) + (*itr2++)) / 2.0;
1788  }
1789 
1790  itr1 += width;
1791 
1792  if (j != (vertical_upper -1))
1793  {
1794  itr2 += width;
1795  }
1796  }
1797 
1798  if (odd_height)
1799  {
1800  for (unsigned int i = 0; i < horizontal_upper; ++i, ++s_itr)
1801  {
1802  (*s_itr) += (*(itr1++));
1803  (*s_itr) += (*(itr1++));
1804  (*s_itr) /= 2.0;
1805  }
1806 
1807  if (odd_width)
1808  {
1809  (*(s_itr++)) = (*itr1);
1810  }
1811  }
1812 }
Here is the call graph for this function:

◆ upsample()

void upsample ( const unsigned int &  width,
const unsigned int &  height,
const double *  source,
unsigned int &  w,
unsigned int &  h,
double *&  dest 
)
inline

Definition at line 1814 of file bitmap_image.hpp.

References bitmap_image::height(), and bitmap_image::width().

1820 {
1821  /* Single channel. */
1822 
1823  w = 2 * width;
1824  h = 2 * height;
1825 
1826  dest = new double[w * h];
1827 
1828  const double* s_itr = source;
1829  double* itr1 = dest;
1830  double* itr2 = dest + w;
1831 
1832  for (unsigned int j = 0; j < height; ++j)
1833  {
1834  for (unsigned int i = 0; i < width; ++i, ++s_itr)
1835  {
1836  *(itr1++) = (*s_itr);
1837  *(itr1++) = (*s_itr);
1838  *(itr2++) = (*s_itr);
1839  *(itr2++) = (*s_itr);
1840  }
1841 
1842  itr1 += w;
1843  itr2 += w;
1844  }
1845 }
Here is the call graph for this function:

◆ weighted_distance() [1/2]

double weighted_distance ( const unsigned char  r0,
const unsigned char  g0,
const unsigned char  b0,
const unsigned char  r1,
const unsigned char  g1,
const unsigned char  b1 
)
inline

Definition at line 2902 of file bitmap_image.hpp.

Referenced by find_nearest_color(), find_nearest_wave_length(), and weighted_distance().

2904 {
2905  const double diff_r = /*0.30 */ (r0 - r1);
2906  const double diff_g = /*0.59 */ (g0 - g1);
2907  const double diff_b = /*0.11 */ (b0 - b1);
2908 
2909  return std::sqrt((diff_r * diff_r) + (diff_g * diff_g) + (diff_b * diff_b));
2910 }
Here is the caller graph for this function:

◆ weighted_distance() [2/2]

double weighted_distance ( const rgb_t  c0,
const rgb_t  c1 
)
inline

Definition at line 2912 of file bitmap_image.hpp.

References rgb_t::blue, rgb_t::green, rgb_t::red, and weighted_distance().

2913 {
2914  return weighted_distance(c0.red, c0.green, c0.blue,
2915  c1.red, c1.green, c1.blue);
2916 }
unsigned char red
unsigned char green
unsigned char blue
double weighted_distance(const unsigned char r0, const unsigned char g0, const unsigned char b0, const unsigned char r1, const unsigned char g1, const unsigned char b1)
Here is the call graph for this function:

◆ ycbcr_to_rgb()

void ycbcr_to_rgb ( const unsigned int &  length,
double *  y,
double *  cb,
double *  cr,
double *  red,
double *  green,
double *  blue 
)
inline

Definition at line 1713 of file bitmap_image.hpp.

1715 {
1716  unsigned int i = 0;
1717 
1718  while (i < length)
1719  {
1720  double y_ = (*y) - 16.0;
1721  double cb_ = (*cb) - 128.0;
1722  double cr_ = (*cr) - 128.0;
1723 
1724  (*red) = 0.000456621 * y_ + 0.00625893 * cr_;
1725  (*green) = 0.000456621 * y_ - 0.00153632 * cb_ - 0.00318811 * cr_;
1726  (*blue) = 0.000456621 * y_ + 0.00791071 * cb_;
1727 
1728  ++i;
1729  ++red; ++green; ++blue;
1730  ++y; ++cb; ++cr;
1731  }
1732 }

Variable Documentation

◆ autumn_colormap

const rgb_t autumn_colormap[1000]

Definition at line 3142 of file bitmap_image.hpp.

Referenced by test18().

◆ copper_colormap

const rgb_t copper_colormap[1000]

Definition at line 3345 of file bitmap_image.hpp.

Referenced by test18().

◆ gray_colormap

const rgb_t gray_colormap[1000]

Definition at line 3548 of file bitmap_image.hpp.

Referenced by test18().

◆ hot_colormap

const rgb_t hot_colormap[1000]

Definition at line 3751 of file bitmap_image.hpp.

Referenced by test18().

◆ hsv_colormap

const rgb_t hsv_colormap[1000]

Definition at line 3954 of file bitmap_image.hpp.

Referenced by test18(), and test20().

◆ jet_colormap

const rgb_t jet_colormap[1000]

Definition at line 4157 of file bitmap_image.hpp.

Referenced by test09(), test15(), test16(), test17(), test18(), and test20().

◆ palette_colormap

const rgb_t palette_colormap[]
Initial value:
= {
{255, 0, 0}, {255, 31, 0}, {255, 63, 0}, {255, 95, 0}, {255, 127, 0},
{255, 159, 0}, {255, 191, 0}, {255, 223, 0}, {255, 255, 0}, {223, 255, 0},
{191, 255, 0}, {159, 255, 0}, {127, 255, 0}, { 95, 255, 0}, { 63, 255, 0},
{ 31, 255, 0}, { 0, 255, 0}, { 0, 255, 31}, { 0, 255, 63}, { 0, 255, 95},
{ 0, 255, 127}, { 0, 255, 159}, { 0, 255, 191}, { 0, 255, 223}, { 0, 255, 255},
{ 0, 223, 255}, { 0, 191, 255}, { 0, 159, 255}, { 0, 127, 255}, { 0, 95, 255},
{ 0, 63, 255}, { 0, 31, 255}, { 0, 0, 255}, { 31, 0, 255}, { 63, 0, 255},
{ 95, 0, 255}, {127, 0, 255}, {159, 0, 255}, {191, 0, 255}, {223, 0, 255},
{255, 0, 255}, {255, 0, 223}, {255, 0, 191}, {255, 0, 159}, {255, 0, 127},
{255, 0, 95}, {255, 0, 63}, {255, 0, 31}, {255, 255, 255}, { 0, 0, 0}
}

Definition at line 3129 of file bitmap_image.hpp.

Referenced by test18(), and test19().

◆ prism_colormap

const rgb_t prism_colormap[1000]

Definition at line 4360 of file bitmap_image.hpp.

Referenced by test18(), and test20().

◆ vga_colormap

const rgb_t vga_colormap[1000]

Definition at line 4563 of file bitmap_image.hpp.

Referenced by test18(), and test20().

◆ yarg_colormap

const rgb_t yarg_colormap[1000]

Definition at line 4766 of file bitmap_image.hpp.

Referenced by test18().