Paul Heidmann Fractal Example  1.0
pngFactory.cpp
Go to the documentation of this file.
1 // Copyright (C) 2014 Paul S. Heidmann
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // For a copy of the GNU General Public License see
14 // <http://www.gnu.org/licenses/>.
15 //
16 // Author contact info:
17 // Paul Heidmann
18 // paul@heidmann.com
19 
20 #include "pngFactory.hpp"
21 
22 #include <algorithm>
23 #include <functional>
24 #include <stdio.h>
25 
27  const std::uint16_t xResolution,
28  const std::uint16_t yResolution,
29  const std::string& pngOutFileName ) :
30  pFileName( pngOutFileName ),
31  xRes( xResolution ),
32  yRes( yResolution ),
33  xMin( 1.0e300 ),
34  xMax( -1.0e300 ),
35  yMin( 1.0e300 ),
36  yMax( -1.0e300 ),
37  xTranslationFactor( 0.0 ),
38  yTranslationFactor( 0.0 ),
39  pngRowPointers( 0 )
40 {
41  this->pxlLst.clear();
42  this->allocatePngImageSpace();
43 }
44 
46 {
47  this->findMinMax();
48  this->translateAllPixels();
49  this->renderAllPixels();
50  this->writePngFile();
51  this->deallocatePngImageSpace();
52 }
53 
55  const long double x,
56  const long double y,
57  const std::uint8_t red,
58  const std::uint8_t green,
59  const std::uint8_t blue )
60 
61 {
62  this->pxlLst.push_back( std::make_tuple(
63  x,
64  y,
65  red,
66  green,
67  blue ) );
68 }
69 
70 const std::uint16_t png::pngFactory::getXRes( void ) const
71 {
72  return( this->xRes );
73 }
74 
75 const std::uint16_t png::pngFactory::getYRes( void ) const
76 {
77  return( this->yRes );
78 }
79 
81 {
82  this->pngRowPointers =
83  new png::pngFactory::pngRowPtrType[this->yRes];
84  for( std::uint16_t i = 0; i < this->yRes; ++i )
85  this->pngRowPointers[i] =
86  new std::uint8_t[(3 * (this->xRes + 1))];
87 }
88 
90 {
91  for( std::uint16_t i = 0; i < this->yRes; ++i )
92  delete[]( this->pngRowPointers[i] );
93  delete[]( this->pngRowPointers );
94 }
95 
97 {
98  ::FILE* pngOutFile( fopen( this->pFileName.c_str(), "wb" ) );
99 
100  this->pngStructPtr = png_create_write_struct(
101  PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
102 
103  this->pngInfoPtr = png_create_info_struct( this->pngStructPtr );
104 
105  png_init_io( this->pngStructPtr, pngOutFile );
106 
107  if ( setjmp( png_jmpbuf( this->pngStructPtr ) ) )
108  {
109  }
110 
111  png_set_IHDR( this->pngStructPtr,
112  this->pngInfoPtr,
113  this->xRes,
114  this->yRes,
115  8,
116  PNG_COLOR_TYPE_RGB,
117  PNG_INTERLACE_NONE,
118  PNG_COMPRESSION_TYPE_BASE,
119  PNG_FILTER_TYPE_BASE );
120 
121  png_write_info( this->pngStructPtr, this->pngInfoPtr );
122 
123  if ( setjmp( png_jmpbuf( this->pngStructPtr ) ) )
124  {
125  }
126 
127  png_write_image( this->pngStructPtr,
128  reinterpret_cast<png_byte**>( this->pngRowPointers ) );
129 
130  if( setjmp(png_jmpbuf( this->pngStructPtr ) ) )
131  {
132  }
133 
134  png_write_end( this->pngStructPtr, NULL );
135 
136  fclose( pngOutFile );
137 }
138 
140  const png::pngFactory::pixelType& p )
141 {
142  const long double curX( std::get<0>(p) );
143  const long double curY( std::get<1>(p) );
144  if( this->xMin > curX )
145  this->xMin = curX;
146  if( this->xMax < curX )
147  this->xMax = curX;
148  if( this->yMin > curY )
149  this->yMin = curY;
150  if( this->yMax < curY )
151  this->yMax = curY;
152 }
153 
155 {
156  std::for_each(
157  this->pxlLst.begin(),
158  this->pxlLst.end(),
159  std::bind(
161  this,
162  std::placeholders::_1 ) );
163 }
164 
166  png::pngFactory::pixelType& p ) const
167 {
168  std::get<0>(p) = this->xTranslationFactor * (std::get<0>(p) - this->xMin);
169  std::get<1>(p) = this->yTranslationFactor * (std::get<1>(p) - this->yMin);
170 }
171 
173 {
174  this->xTranslationFactor =
175  static_cast<long double>( this->xRes ) / (this->xMax - this->xMin);
176  this->yTranslationFactor =
177  static_cast<long double>( this->yRes ) / (this->yMax - this->yMin);
178  std::for_each(
179  this->pxlLst.begin(),
180  this->pxlLst.end(),
181  std::bind(
183  this,
184  std::placeholders::_1 ) );
185 }
186 
188 {
189  const std::list<png::pngFactory::pixelType>::const_iterator
190  end( this->pxlLst.end() );
191 
192  std::list<png::pngFactory::pixelType>::const_iterator i;
193  for( i = this->pxlLst.begin();
194  i != end;
195  ++i )
196  {
197  const int x( static_cast<int>( std::get<0>(*i) ) );
198  const int y( static_cast<int>( std::get<1>(*i) ) );
199 
200  if( (x < this->xRes) && (y < this->yRes) &&
201  (x >= 0) && (y >= 0) )
202  {
203  std::uint8_t*
204  pix( &(this->pngRowPointers[y][3*x]) );
205  *pix = std::get<2>(*i);
206  ++pix;
207  *pix = std::get<3>(*i);
208  ++pix;
209  *pix = std::get<4>(*i);
210  ++pix;
211  }
212  }
213 }
void translatePixel(png::pngFactory::pixelType &p) const
This method maps a single pixel from the user specified coordinate plane to pixel space...
Definition: pngFactory.cpp:165
std::tuple< long double, long double, std::uint8_t, std::uint8_t, std::uint8_t > pixelType
This type is used to define variables that hold single pixels.
Definition: pngFactory.hpp:87
~pngFactory()
The class destructor.
Definition: pngFactory.cpp:45
void renderAllPixels(void)
This method renders all pixels.
Definition: pngFactory.cpp:187
std::list< png::pngFactory::pixelType > pxlLst
This attribute holds all caller specified pixels.
Definition: pngFactory.hpp:127
void updateMinMax(const png::pngFactory::pixelType &p)
This method is called to update the minimums and maximums, as tracked by this instance.
Definition: pngFactory.cpp:139
void writePngFile(void)
This method writes the PNG image out to disk.
Definition: pngFactory.cpp:96
const std::uint16_t getXRes(void) const
This method returns to the caller the horizontal resolution of the image.
Definition: pngFactory.cpp:70
void translateAllPixels(void)
This method maps all pixels from the user specified coordinate plane to pixel space.
Definition: pngFactory.cpp:172
std::uint8_t * pngRowPtrType
This type is used to access rows in the PNG image.
Definition: pngFactory.hpp:90
pngFactory()=delete
void findMinMax(void)
This method is called to determine the minimums and maximums, as tracked by this instance.
Definition: pngFactory.cpp:154
void deallocatePngImageSpace(void)
This method deallocates the PNG image space.
Definition: pngFactory.cpp:89
void addPixel(const long double x, const long double y, const std::uint8_t red, const std::uint8_t green, const std::uint8_t blue)
This method is called to add a pixel to the PNG image.
Definition: pngFactory.cpp:54
const std::uint16_t getYRes(void) const
This method returns to the caller the vertical resolution of the image.
Definition: pngFactory.cpp:75
void allocatePngImageSpace(void)
This method allocates space from the heap to hold the PNG image.
Definition: pngFactory.cpp:80