doxygen: intern/smoke tagged.
[blender.git] / intern / smoke / intern / IMAGE.h
1 /** \file smoke/intern/IMAGE.h
2  *  \ingroup smoke
3  */
4 //////////////////////////////////////////////////////////////////////
5 // This file is part of Wavelet Turbulence.
6 //
7 // Wavelet Turbulence is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // Wavelet Turbulence is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with Wavelet Turbulence.  If not, see <http://www.gnu.org/licenses/>.
19 //
20 // Copyright 2008 Theodore Kim and Nils Thuerey
21 //
22 //////////////////////////////////////////////////////////////////////
23 //
24 #ifndef IMAGE_H
25 #define IMAGE_H
26
27 #include <stdlib.h>
28 #include <string>
29 #include <fstream>
30 #include <sstream>
31 #include <zlib.h>
32
33 //////////////////////////////////////////////////////////////////////
34 // NT helper functions
35 //////////////////////////////////////////////////////////////////////
36 template < class T > inline T ABS( T a ) {
37         return (0 < a) ? a : -a ;
38 }
39
40 template < class T > inline void SWAP_POINTERS( T &a, T &b ) {
41         T temp = a;
42         a = b;
43         b = temp;
44 }
45
46 template < class T > inline void CLAMP( T &a, T b=0., T c=1.) {
47         if(a<b) { a=b; return; }
48         if(a>c) { a=c; return; }
49 }
50
51 template < class T > inline T MIN( T a, T b) {
52         return (a < b) ? a : b;
53 }
54
55 template < class T > inline T MAX( T a, T b) {
56         return (a > b) ? a : b;
57 }
58
59 template < class T > inline T MAX3( T a, T b, T c) {
60         T max = (a > b) ? a : b;
61         max = (max > c) ? max : c;
62         return max;
63 }
64
65 template < class T > inline float MAX3V( T vec) {
66         float max = (vec[0] > vec[1]) ? vec[0] : vec[1];
67         max = (max > vec[2]) ? max : vec[2];
68         return max;
69 }
70
71 template < class T > inline float MIN3V( T vec) {
72         float min = (vec[0] < vec[1]) ? vec[0] : vec[1];
73         min = (min < vec[2]) ? min : vec[2];
74         return min;
75 }
76
77 //////////////////////////////////////////////////////////////////////
78 // PNG, POV-Ray, and PBRT output functions
79 //////////////////////////////////////////////////////////////////////
80 #ifndef NOPNG
81 #ifdef WIN32
82 #include "png.h"
83 #else
84 #include <png.h>
85 #endif
86 #endif // NOPNG
87
88 /*
89   NOTE when someone decided to uncomment the following code, please remember to put it between #ifndef NOPNG #endif
90 */
91 namespace IMAGE {
92         /*
93   static int writePng(const char *fileName, unsigned char **rowsp, int w, int h)
94   {
95     // defaults
96     const int colortype = PNG_COLOR_TYPE_RGBA;
97     const int bitdepth = 8;
98     png_structp png_ptr = NULL;
99     png_infop info_ptr = NULL;
100     png_bytep *rows = rowsp;
101
102     FILE *fp = NULL;
103     std::string doing = "open for writing";
104     if (!(fp = fopen(fileName, "wb"))) goto fail;
105
106     if(!png_ptr) {
107       doing = "create png write struct";
108       if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) goto fail;
109     }
110     if(!info_ptr) {
111       doing = "create png info struct";
112       if (!(info_ptr = png_create_info_struct(png_ptr))) goto fail;
113     }
114
115     if (setjmp(png_jmpbuf(png_ptr))) goto fail;
116     doing = "init IO";
117     png_init_io(png_ptr, fp);
118     doing = "write header";
119     png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth, colortype, PNG_INTERLACE_NONE,
120         PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
121     doing = "write info";
122     png_write_info(png_ptr, info_ptr);
123     doing = "write image";
124     png_write_image(png_ptr, rows);
125     doing = "write end";
126     png_write_end(png_ptr, NULL);
127     doing = "write destroy structs";
128     png_destroy_write_struct(&png_ptr, &info_ptr);
129
130     fclose( fp );
131     return 0;
132
133   fail:
134     std::cerr << "writePng: could not "<<doing<<" !\n";
135     if(fp) fclose( fp );
136     if(png_ptr || info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
137     return -1;
138   }
139   */
140
141   /////////////////////////////////////////////////////////////////////////////////
142   // write a numbered PNG file out, padded with zeros up to three zeros
143   /////////////////////////////////////////////////////////////////////////////////
144   /*
145   static void dumpNumberedPNG(int counter, std::string prefix, float* field, int xRes, int yRes)
146   {
147         char buffer[256];
148     sprintf(buffer,"%04i", counter);
149     std::string number = std::string(buffer);
150
151     unsigned char pngbuf[xRes*yRes*4];
152     unsigned char *rows[yRes];
153     float *pfield = field;
154     for (int j=0; j<yRes; j++) {
155       for (int i=0; i<xRes; i++) {
156         float val = *pfield;
157         if(val>1.) val=1.;
158         if(val<0.) val=0.;
159         pngbuf[(j*xRes+i)*4+0] = (unsigned char)(val*255.);
160         pngbuf[(j*xRes+i)*4+1] = (unsigned char)(val*255.);
161         pngbuf[(j*xRes+i)*4+2] = (unsigned char)(val*255.);
162         pfield++;
163         pngbuf[(j*xRes+i)*4+3] = 255;
164       }
165       rows[j] = &pngbuf[(yRes-j-1)*xRes*4];
166     }
167     std::string filenamePNG = prefix + number + std::string(".png");
168     writePng(filenamePNG.c_str(), rows, xRes, yRes, false);
169     printf("Writing %s\n", filenamePNG.c_str());
170    
171   }
172 */
173   /////////////////////////////////////////////////////////////////////////////////
174   // export pbrt volumegrid geometry object
175   /////////////////////////////////////////////////////////////////////////////////
176         /*
177   static void dumpPBRT(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes)
178   {
179     char buffer[256];
180     sprintf(buffer,"%04i", counter);
181     std::string number = std::string(buffer);
182
183     std::string filenamePbrt = prefix + number + std::string(".pbrt.gz");
184     printf("Writing PBRT %s\n", filenamePbrt.c_str());
185
186     float *field = new float[xRes*yRes*zRes];
187     // normalize values
188     float maxDensVal = ABS(fieldOrg[0]);
189     float targetNorm = 0.5;
190     for (int i = 0; i < xRes * yRes * zRes; i++) {
191       if(ABS(fieldOrg[i])>maxDensVal) maxDensVal = ABS(fieldOrg[i]);
192       field[i] = 0.;
193     }
194     if(maxDensVal>0.) {
195       for (int i = 0; i < xRes * yRes * zRes; i++) {
196         field[i] = ABS(fieldOrg[i]) / maxDensVal * targetNorm;
197       }
198     }
199
200     std::fstream fout;
201     fout.open(filenamePbrt.c_str(), std::ios::out);
202
203     int maxRes = (xRes > yRes) ? xRes : yRes;
204     maxRes = (maxRes > zRes) ? maxRes : zRes;
205
206     const float xSize = 1.0 / (float)maxRes * (float)xRes;
207     const float ySize = 1.0 / (float)maxRes * (float)yRes;
208     const float zSize = 1.0 / (float)maxRes * (float)zRes;
209
210     gzFile file;
211     file = gzopen(filenamePbrt.c_str(), "wb1");
212     if (file == NULL) {
213       std::cerr << " Couldn't write file " << filenamePbrt << "!!!" << std::endl;
214       return;
215     }
216
217     // dimensions
218     gzprintf(file, "Volume \"volumegrid\" \n");
219     gzprintf(file, " \"integer nx\" %i\n", xRes);
220     gzprintf(file, " \"integer ny\" %i\n", yRes);
221     gzprintf(file, " \"integer nz\" %i\n", zRes);
222     gzprintf(file, " \"point p0\" [ 0.0 0.0 0.0 ] \"point p1\" [%f %f %f ] \n", xSize, ySize, zSize);
223     gzprintf(file, " \"float density\" [ \n");
224     for (int i = 0; i < xRes * yRes * zRes; i++)
225       gzprintf(file, "%f ", field[i]);
226     gzprintf(file, "] \n \n");
227
228     gzclose(file);
229     delete[] field;
230   }
231   */
232
233   /////////////////////////////////////////////////////////////////////////////////
234   // 3D df3 export
235   /////////////////////////////////////////////////////////////////////////////////
236 /*
237   static void dumpDF3(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes)
238   {
239     char buffer[256];
240
241     // do deferred copying to final directory, better for network directories
242     sprintf(buffer,"%04i", counter);
243     std::string number = std::string(buffer);
244     std::string filenameDf3 = prefix + number + std::string(".df3.gz");
245     printf("Writing DF3 %s\n", filenameDf3.c_str());
246
247     gzFile file;
248     file = gzopen(filenameDf3.c_str(), "wb1");
249     if (file == NULL) {
250       std::cerr << " Couldn't write file " << filenameDf3 << "!!!" << std::endl;
251       return;
252     }
253
254     // dimensions
255     const int byteSize = 2;
256     const unsigned short int onx=xRes,ony=yRes,onz=zRes;
257     unsigned short int nx,ny,nz;
258     nx = onx >> 8;
259     ny = ony >> 8;
260     nz = onz >> 8;
261     nx += (onx << 8);
262     ny += (ony << 8);
263     nz += (onz << 8);
264     gzwrite(file, (void*)&nx, sizeof(short));
265     gzwrite(file, (void*)&ny, sizeof(short));
266     gzwrite(file, (void*)&nz, sizeof(short));
267     const int nitems = onx*ony*onz;
268     const float mul = (float)( (1<<(8*byteSize))-1);
269
270     unsigned short int *buf = new unsigned short int[nitems];
271     for (int k = 0; k < onz; k++)
272       for (int j = 0; j < ony; j++)
273         for (int i = 0; i < onx; i++) {
274           float val = fieldOrg[k*(onx*ony)+j*onx+i] ;
275           CLAMP(val);
276           buf[k*(onx*ony)+j*onx+i] = (short int)(val*mul);
277         }
278     gzwrite(file, (void*)buf, sizeof(unsigned short int)* nitems);
279
280     gzclose(file);
281     delete[] buf;
282   }
283   */
284
285 };
286
287
288 #endif
289