Blender V2.61 - r43446

IMAGE.h

Go to the documentation of this file.
00001 
00004 
00005 // This file is part of Wavelet Turbulence.
00006 //
00007 // Wavelet Turbulence is free software: you can redistribute it and/or modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation, either version 3 of the License, or
00010 // (at your option) any later version.
00011 //
00012 // Wavelet Turbulence is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Wavelet Turbulence.  If not, see <http://www.gnu.org/licenses/>.
00019 //
00020 // Copyright 2008 Theodore Kim and Nils Thuerey
00021 //
00023 //
00024 #ifndef IMAGE_H
00025 #define IMAGE_H
00026 
00027 #include <stdlib.h>
00028 #include <string>
00029 #include <fstream>
00030 #include <sstream>
00031 #include <zlib.h>
00032 
00034 // NT helper functions
00036 template < class T > inline T ABS( T a ) {
00037     return (0 < a) ? a : -a ;
00038 }
00039 
00040 template < class T > inline void SWAP_POINTERS( T &a, T &b ) {
00041     T temp = a;
00042     a = b;
00043     b = temp;
00044 }
00045 
00046 template < class T > inline void CLAMP( T &a, T b=0., T c=1.) {
00047     if(a<b) { a=b; return; }
00048     if(a>c) { a=c; return; }
00049 }
00050 
00051 template < class T > inline T MIN( T a, T b) {
00052     return (a < b) ? a : b;
00053 }
00054 
00055 template < class T > inline T MAX( T a, T b) {
00056     return (a > b) ? a : b;
00057 }
00058 
00059 template < class T > inline T MAX3( T a, T b, T c) {
00060     T max = (a > b) ? a : b;
00061     max = (max > c) ? max : c;
00062     return max;
00063 }
00064 
00065 template < class T > inline float MAX3V( T vec) {
00066     float max = (vec[0] > vec[1]) ? vec[0] : vec[1];
00067     max = (max > vec[2]) ? max : vec[2];
00068     return max;
00069 }
00070 
00071 template < class T > inline float MIN3V( T vec) {
00072     float min = (vec[0] < vec[1]) ? vec[0] : vec[1];
00073     min = (min < vec[2]) ? min : vec[2];
00074     return min;
00075 }
00076 
00078 // PNG, POV-Ray, and PBRT output functions
00080 #ifndef NOPNG
00081 #ifdef WIN32
00082 #include "png.h"
00083 #else
00084 #include <png.h>
00085 #endif
00086 #endif // NOPNG
00087 
00088 /*
00089   NOTE when someone decided to uncomment the following code, please remember to put it between #ifndef NOPNG #endif
00090 */
00091 namespace IMAGE {
00092     /*
00093   static int writePng(const char *fileName, unsigned char **rowsp, int w, int h)
00094   {
00095     // defaults
00096     const int colortype = PNG_COLOR_TYPE_RGBA;
00097     const int bitdepth = 8;
00098     png_structp png_ptr = NULL;
00099     png_infop info_ptr = NULL;
00100     png_bytep *rows = rowsp;
00101 
00102     FILE *fp = NULL;
00103     std::string doing = "open for writing";
00104     if (!(fp = fopen(fileName, "wb"))) goto fail;
00105 
00106     if(!png_ptr) {
00107       doing = "create png write struct";
00108       if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) goto fail;
00109     }
00110     if(!info_ptr) {
00111       doing = "create png info struct";
00112       if (!(info_ptr = png_create_info_struct(png_ptr))) goto fail;
00113     }
00114 
00115     if (setjmp(png_jmpbuf(png_ptr))) goto fail;
00116     doing = "init IO";
00117     png_init_io(png_ptr, fp);
00118     doing = "write header";
00119     png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth, colortype, PNG_INTERLACE_NONE,
00120         PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
00121     doing = "write info";
00122     png_write_info(png_ptr, info_ptr);
00123     doing = "write image";
00124     png_write_image(png_ptr, rows);
00125     doing = "write end";
00126     png_write_end(png_ptr, NULL);
00127     doing = "write destroy structs";
00128     png_destroy_write_struct(&png_ptr, &info_ptr);
00129 
00130     fclose( fp );
00131     return 0;
00132 
00133   fail:
00134     std::cerr << "writePng: could not "<<doing<<" !\n";
00135     if(fp) fclose( fp );
00136     if(png_ptr || info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
00137     return -1;
00138   }
00139   */
00140 
00142   // write a numbered PNG file out, padded with zeros up to three zeros
00144   /*
00145   static void dumpNumberedPNG(int counter, std::string prefix, float* field, int xRes, int yRes)
00146   {
00147     char buffer[256];
00148     sprintf(buffer,"%04i", counter);
00149     std::string number = std::string(buffer);
00150 
00151     unsigned char pngbuf[xRes*yRes*4];
00152     unsigned char *rows[yRes];
00153     float *pfield = field;
00154     for (int j=0; j<yRes; j++) {
00155       for (int i=0; i<xRes; i++) {
00156         float val = *pfield;
00157         if(val>1.) val=1.;
00158         if(val<0.) val=0.;
00159         pngbuf[(j*xRes+i)*4+0] = (unsigned char)(val*255.);
00160         pngbuf[(j*xRes+i)*4+1] = (unsigned char)(val*255.);
00161         pngbuf[(j*xRes+i)*4+2] = (unsigned char)(val*255.);
00162         pfield++;
00163         pngbuf[(j*xRes+i)*4+3] = 255;
00164       }
00165       rows[j] = &pngbuf[(yRes-j-1)*xRes*4];
00166     }
00167     std::string filenamePNG = prefix + number + std::string(".png");
00168     writePng(filenamePNG.c_str(), rows, xRes, yRes, false);
00169     printf("Writing %s\n", filenamePNG.c_str());
00170    
00171   }
00172 */
00174   // export pbrt volumegrid geometry object
00176     /*
00177   static void dumpPBRT(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes)
00178   {
00179     char buffer[256];
00180     sprintf(buffer,"%04i", counter);
00181     std::string number = std::string(buffer);
00182 
00183     std::string filenamePbrt = prefix + number + std::string(".pbrt.gz");
00184     printf("Writing PBRT %s\n", filenamePbrt.c_str());
00185 
00186     float *field = new float[xRes*yRes*zRes];
00187     // normalize values
00188     float maxDensVal = ABS(fieldOrg[0]);
00189     float targetNorm = 0.5;
00190     for (int i = 0; i < xRes * yRes * zRes; i++) {
00191       if(ABS(fieldOrg[i])>maxDensVal) maxDensVal = ABS(fieldOrg[i]);
00192       field[i] = 0.;
00193     }
00194     if(maxDensVal>0.) {
00195       for (int i = 0; i < xRes * yRes * zRes; i++) {
00196         field[i] = ABS(fieldOrg[i]) / maxDensVal * targetNorm;
00197       }
00198     }
00199 
00200     std::fstream fout;
00201     fout.open(filenamePbrt.c_str(), std::ios::out);
00202 
00203     int maxRes = (xRes > yRes) ? xRes : yRes;
00204     maxRes = (maxRes > zRes) ? maxRes : zRes;
00205 
00206     const float xSize = 1.0 / (float)maxRes * (float)xRes;
00207     const float ySize = 1.0 / (float)maxRes * (float)yRes;
00208     const float zSize = 1.0 / (float)maxRes * (float)zRes;
00209 
00210     gzFile file;
00211     file = gzopen(filenamePbrt.c_str(), "wb1");
00212     if (file == NULL) {
00213       std::cerr << " Couldn't write file " << filenamePbrt << "!!!" << std::endl;
00214       return;
00215     }
00216 
00217     // dimensions
00218     gzprintf(file, "Volume \"volumegrid\" \n");
00219     gzprintf(file, " \"integer nx\" %i\n", xRes);
00220     gzprintf(file, " \"integer ny\" %i\n", yRes);
00221     gzprintf(file, " \"integer nz\" %i\n", zRes);
00222     gzprintf(file, " \"point p0\" [ 0.0 0.0 0.0 ] \"point p1\" [%f %f %f ] \n", xSize, ySize, zSize);
00223     gzprintf(file, " \"float density\" [ \n");
00224     for (int i = 0; i < xRes * yRes * zRes; i++)
00225       gzprintf(file, "%f ", field[i]);
00226     gzprintf(file, "] \n \n");
00227 
00228     gzclose(file);
00229     delete[] field;
00230   }
00231   */
00232 
00234   // 3D df3 export
00236 /*
00237   static void dumpDF3(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes)
00238   {
00239     char buffer[256];
00240 
00241     // do deferred copying to final directory, better for network directories
00242     sprintf(buffer,"%04i", counter);
00243     std::string number = std::string(buffer);
00244     std::string filenameDf3 = prefix + number + std::string(".df3.gz");
00245     printf("Writing DF3 %s\n", filenameDf3.c_str());
00246 
00247     gzFile file;
00248     file = gzopen(filenameDf3.c_str(), "wb1");
00249     if (file == NULL) {
00250       std::cerr << " Couldn't write file " << filenameDf3 << "!!!" << std::endl;
00251       return;
00252     }
00253 
00254     // dimensions
00255     const int byteSize = 2;
00256     const unsigned short int onx=xRes,ony=yRes,onz=zRes;
00257     unsigned short int nx,ny,nz;
00258     nx = onx >> 8;
00259     ny = ony >> 8;
00260     nz = onz >> 8;
00261     nx += (onx << 8);
00262     ny += (ony << 8);
00263     nz += (onz << 8);
00264     gzwrite(file, (void*)&nx, sizeof(short));
00265     gzwrite(file, (void*)&ny, sizeof(short));
00266     gzwrite(file, (void*)&nz, sizeof(short));
00267     const int nitems = onx*ony*onz;
00268     const float mul = (float)( (1<<(8*byteSize))-1);
00269 
00270     unsigned short int *buf = new unsigned short int[nitems];
00271     for (int k = 0; k < onz; k++)
00272       for (int j = 0; j < ony; j++)
00273         for (int i = 0; i < onx; i++) {
00274           float val = fieldOrg[k*(onx*ony)+j*onx+i] ;
00275           CLAMP(val);
00276           buf[k*(onx*ony)+j*onx+i] = (short int)(val*mul);
00277         }
00278     gzwrite(file, (void*)buf, sizeof(unsigned short int)* nitems);
00279 
00280     gzclose(file);
00281     delete[] buf;
00282   }
00283   */
00284 
00285 };
00286 
00287 
00288 #endif
00289