1 /*
2  * This file is part of Filmulator.
3  *
4  * Copyright 2013 Omer Mano and Carlo Vaccari
5  *
6  * Filmulator 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  * Filmulator 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 Filmulator. If not, see <http://www.gnu.org/licenses/>
18  */
19 #include "filmSim.hpp"
20 
ppmb_write_data(ofstream & output,int xsize,int ysize,matrix<float> & densityr,matrix<float> & densityg,matrix<float> & densityb,bool sixteen_bit)21 bool ppmb_write_data ( ofstream &output, int xsize, int ysize,
22   matrix<float> &densityr, matrix<float> &densityg, matrix<float> &densityb,
23   bool sixteen_bit )
24 
25 //****************************************************************************80
26 //
27 //  Purpose:
28 //
29 //    PPMB_WRITE_DATA writes the data for a binary portable pixel map file.
30 //
31 //  Licensing:
32 //
33 //    This code is distributed under the GNU LGPL license.
34 //
35 //  Modified:
36 //
37 //    11 April 2003
38 //
39 //  Author:
40 //
41 //    John Burkardt
42 //
43 //  Parameters:
44 //
45 //    Input, ofstream OUTPUT, a pointer to the file to contain the binary
46 //    portable pixel map data.
47 //
48 //    Input, int XSIZE, YSIZE, the number of rows and columns of data.
49 //
50 //    Input, unsigned char *R, *G, *B, the arrays of XSIZE by YSIZE
51 //    data values.
52 //
53 //    Output, bool PPMB_WRITE_DATA, is true if an error occurred.
54 //
55 {
56     int  i;
57     int  j;
58     unsigned short out;
59     unsigned char out2;
60 
61     if(sixteen_bit)
62     {
63       for ( j = 0; j < ysize; j++ )
64       {
65         for ( i = 0; i < xsize; i++ )
66         {
67           if(densityr(j,i) > 65535)
68             out = 65535; //clip to white
69           else if(densityr(j,i) < 0)
70             out = 0; //clip to black
71           else
72           out = (unsigned short) densityr(j,i); //normal values
73           out   = ((out   & 0x00ff)<<8)|((out   & 0xff00)>>8);
74           output.write(reinterpret_cast<char*>(&out), sizeof(unsigned short));
75 
76           if(densityg(j,i) > 65535)
77             out = 65535; //clip to white
78           else if(densityg(j,i) < 0)
79             out = 0; //clip to black
80           else
81             out = (unsigned short) densityg(j,i); //normal values
82           out   = ((out   & 0x00ff)<<8)|((out   & 0xff00)>>8);
83           output.write(reinterpret_cast<char*>(&out), sizeof(unsigned short));
84 
85           if(densityb(j,i) > 65535)
86             out = 65535; //clip to white
87           else if(densityb(j,i) < 0)
88             out = 0; //clip to black
89           else
90           out = (unsigned short) densityb(j,i); //normal values
91           out   = ((out   & 0x00ff)<<8)|((out   & 0xff00)>>8);
92           output.write(reinterpret_cast<char*>(&out), sizeof(unsigned short));
93         }
94       }
95     }
96     else //8 bit
97     {
98       for ( j = 0; j < ysize; j++ )
99       {
100         for ( i = 0; i < xsize; i++ )
101         {
102           if(densityr(j,i) > 255)
103             out2 = 255; //clip to white
104           else if(densityr(j,i) < 0)
105             out2 = 0; //clip to black
106           else
107           out2 = (unsigned char) densityr(j,i); //normal values
108           output.write(reinterpret_cast<char*>(&out2), sizeof(unsigned char));
109 
110           if(densityg(j,i) > 255)
111             out2 = 255; //clip to white
112           else if(densityg(j,i) < 0)
113             out2 = 0; //clip to black
114           else
115           out2 = (unsigned char) densityg(j,i); //normal values
116           output.write(reinterpret_cast<char*>(&out2), sizeof(unsigned char));
117 
118           if(densityb(j,i) > 255)
119             out2 = 255; //clip to white
120           else if(densityb(j,i) < 0)
121             out2 = 0; //clip to black
122           else
123           out2 = (unsigned char) densityb(j,i); //normal values
124           output.write(reinterpret_cast<char*>(&out2), sizeof(unsigned char));
125         }
126       }
127     }
128     return false;
129 }
130 //****************************************************************************80
131 
ppmb_write_header(ofstream & output,int xsize,int ysize,int maxrgb)132 bool ppmb_write_header ( ofstream &output, int xsize, int ysize, int maxrgb )
133 
134 //****************************************************************************80
135 //
136 //  Purpose:
137 //
138 //    PPMB_WRITE_HEADER writes the header of a binary portable pixel map file.
139 //
140 //  Licensing:
141 //
142 //    This code is distributed under the GNU LGPL license.
143 //
144 //  Modified:
145 //
146 //    11 April 2003
147 //
148 //  Author:
149 //
150 //    John Burkardt
151 //
152 //  Parameters:
153 //
154 //    Input, ofstream &OUTPUT, a pointer to the file to contain the binary
155 //    portable pixel map data.
156 //
157 //    Input, int XSIZE, YSIZE, the number of rows and columns of data.
158 //
159 //    Input, int MAXRGB, the maximum RGB value.
160 //
161 //    Output, bool PPMB_WRITE_HEADER, is true if an error occurred.
162 //
163 {
164   output << "P6"   << " "
165            << xsize  << " "
166            << ysize  << " "
167            << maxrgb << "\n";
168 
169   return false;
170 }
171 
172 
imwrite(matrix<float> & densityr,matrix<float> & densityg,matrix<float> & densityb,string output_name,bool sixteen_bit)173 void imwrite(matrix<float> &densityr, matrix<float> &densityg,
174     matrix<float> &densityb, string output_name, bool sixteen_bit )
175 {
176   bool error;
177   ofstream output;
178   int maxrgb;
179   int xsize = densityr.nc();
180   int ysize = densityr.nr();
181 //
182 //  Open the output file.
183 //
184   output.open ( output_name.c_str( ), ios::binary );
185 
186   if ( !output )
187   {
188     cout << "\n";
189     cout << "PPMB_WRITE: Fatal error!\n";
190     cout << "  Cannot open the output file " << output_name << ".\n";
191     return;
192   }
193 //
194 //  Compute the maximum.
195 //
196   if ( sixteen_bit)
197     maxrgb = 65535;
198   else
199     maxrgb = 255;
200 //
201 //  Write the header.
202 //
203   error = ppmb_write_header ( output, xsize, ysize, maxrgb );
204 
205   if ( error )
206   {
207     cout << "\n";
208     cout << "PPMB_WRITE: Fatal error!\n";
209     cout << "  PPMB_WRITE_HEADER failed.\n";
210     return;
211   }
212 //
213 //  Write the data.
214 //
215   error = ppmb_write_data ( output, xsize, ysize, densityr, densityg, densityb,
216     sixteen_bit);
217 
218   if ( error )
219   {
220     cout << "\n";
221     cout << "PPMB_WRITE: Fatal error!\n";
222     cout << "  PPMB_WRITE_DATA failed.\n";
223     return;
224   }
225 //
226 //  Close the file.
227 //
228   output.close ( );
229 
230   return;
231 }
232