1 /**************************************************************************/
2 /*  Copyright 2009 Tim Day                                                */
3 /*                                                                        */
4 /*  This file is part of Fracplanet                                       */
5 /*                                                                        */
6 /*  Fracplanet is free software: you can redistribute it and/or modify    */
7 /*  it under the terms of the GNU General Public License as published by  */
8 /*  the Free Software Foundation, either version 3 of the License, or     */
9 /*  (at your option) any later version.                                   */
10 /*                                                                        */
11 /*  Fracplanet is distributed in the hope that it will be useful,         */
12 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
13 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
14 /*  GNU General Public License for more details.                          */
15 /*                                                                        */
16 /*  You should have received a copy of the GNU General Public License     */
17 /*  along with Fracplanet.  If not, see <http://www.gnu.org/licenses/>.   */
18 /**************************************************************************/
19 
20 /*! \file
21   \brief Implementation for templated Image class.
22 */
23 
24 #include "image.h"
25 
26 #include "progress.h"
27 #include "rgb.h"
28 
fill(const T & v)29 template <typename T> void Raster<T>::fill(const T& v)
30 {
31   if (contiguous())
32     {
33       std::fill(contiguous_begin(),contiguous_end(),v);
34     }
35   else
36     {
37       for (RowIterator row=row_begin();row!=row_end();++row)
38 	std::fill((*row).begin(),(*row).end(),v);
39     }
40 }
41 
maximum_scalar_pixel_value() const42 template <typename T> const typename Raster<T>::ScalarType Raster<T>::maximum_scalar_pixel_value() const
43 {
44   ScalarType m(scalar(*_data));
45   for (ConstRowIterator row=row_begin();row!=row_end();++row)
46     for (const T* it=row->begin();it!=row->end();++it)
47       {
48 	const ScalarType v(scalar(*it));
49 	if (v>m) m=v;
50       }
51   return m;
52 }
53 
write_pgmfile(const std::string & filename,Progress * target) const54 template <> bool Raster<uchar>::write_pgmfile(const std::string& filename,Progress* target) const
55 {
56   ProgressScope progress(height(),"Writing PGM image:\n"+filename,target);
57   std::ofstream out(filename.c_str(),std::ios::binary);
58   out << "P5" << std::endl;
59   out << width() << " " << height() << std::endl;
60   out << "255" << std::endl;
61   for (ConstRowIterator row=row_begin();row!=row_end();++row)
62     {
63       progress.step();
64       out.write(reinterpret_cast<const char*>(&(*(row->begin()))),row->size());
65     }
66   out.close();
67   return static_cast<bool>(out);
68 }
69 
write_pgmfile(const std::string & filename,Progress * target) const70 template <> bool Raster<ushort>::write_pgmfile(const std::string& filename,Progress* target) const
71 {
72   ProgressScope progress(height(),"Writing PGM image:\n"+filename,target);
73   std::ofstream out(filename.c_str(),std::ios::binary);
74   out << "P5" << std::endl;
75   out << width() << " " << height() << std::endl;
76   const ushort m=maximum_scalar_pixel_value();
77   out << m << std::endl;
78   for (ConstRowIterator row=row_begin();row!=row_end();++row)
79     {
80       progress.step();
81       for (const ushort* it=row->begin();it!=row->end();++it)
82 	{
83 	  const uchar p[2]={uchar((*it)>>8),uchar(*it)};
84 	  if (m>=256)
85 	    {
86 	      // PGM spec is most significant byte first
87 	      out.write(reinterpret_cast<const char*>(p),2);
88 	    }
89 	  else
90 	    {
91 	      assert(p[0]==0);
92 	      out.write(reinterpret_cast<const char*>(p+1),1);
93 	    }
94 	}
95     }
96   out.close();
97   return static_cast<bool>(out);
98 }
99 
write_ppmfile(const std::string & filename,Progress * target) const100 template <> bool Raster<ByteRGBA>::write_ppmfile(const std::string& filename,Progress* target) const
101 {
102   ProgressScope progress(height(),"Writing PPM image:\n"+filename,target);
103   std::ofstream out(filename.c_str(),std::ios::binary);
104   out << "P6" << std::endl;
105   out << width() << " " << height() << std::endl;
106   out << "255" << std::endl;
107   for (ConstRowIterator row=row_begin();row!=row_end();++row)
108     {
109       progress.step();
110       for (const ByteRGBA* it=row->begin();it!=row->end();++it)
111 	out.write(reinterpret_cast<const char*>(&((*it).r)),3);
112     }
113   out.close();
114   return static_cast<bool>(out);
115 }
116 
117 
118 template class Raster<uchar>;
119 template class Image<uchar>;
120 
121 template class Raster<ushort>;
122 template class Image<ushort>;
123 
124 template class Raster<ByteRGBA>;
125 template class Image<ByteRGBA>;
126 
127