/**************************************************************************** * BIOC -- Biomorph Generator - BMP and TIFF format (color) * * Coded by Carlos Suberviola Oroz. * * * * Copyright (c) 2002 Carlos Suberviola Oroz -- http://biomorph.tk * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation as version 2 of the License. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * ****************************************************************************/ #include #include #include #include #include #include #include #include #include using namespace std; const char _c_[] = "Made by BioC - (c) 2002 Carlos Suberviola Oroz - " ""; #define DIMOF(a) (sizeof(a)/sizeof((a)[0])) #define min(a,b) ((a)<(b)?(a):(b)) typedef double complex_t__value_type; typedef complex complex_t; typedef complex_t (*pfcpx_t)(complex_t&); complex_t N, M, _c; pfcpx_t _f; complex_t f0 (complex_t& z) { return sin(z) + complex_t__value_type(exp(real(z))) * complex_t(cos(real(z)), sin(imag(z))); } complex_t f1 (complex_t& z) { return pow(z,N); } complex_t f2 (complex_t& z) { return pow(z,N)+pow(z,M); } complex_t f3 (complex_t& z) { return pow(z,z); } complex_t f4 (complex_t& z) { return pow(z,z)+pow(z,N); } complex_t f5 (complex_t& z) { return sin(z); } complex_t f6 (complex_t& z) { return sin(z)+pow(z,N); } complex_t f7 (complex_t& z) { return sin(z)+exp(z); } complex_t f8 (complex_t& z) { return sin(z)+pow(N,z); } complex_t f9 (complex_t& z) { return sin(z)+pow(z,z); } complex_t f10 (complex_t& z) { return sin(z)/cos(z)+pow(z,N); } complex_t f11 (complex_t& z) { return log(z)+pow(z,N); } const pfcpx_t Function[] = { f0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11 }; const char* FunctExpr[] = { "sin(z) + e^Re(z)*[cos(Re(z))+i*sin(Im(z))]", "z^N","z^N + z^M","z^z","z^z + z^N", "sin(z)","sin(z) + z^N","sin(z) + e^z","sin(z) + N^z","sin(z) + z^z", "tan(z) + z^N","log(z) + z^N" }; enum FileFormat { FORMAT_NONE = 0, FORMAT_TIFF = 1, FORMAT_BMP = 2, }; struct params_t { unsigned Q; unsigned X, Y; complex_t z0; complex_t__value_type w; const char *name; FileFormat format; unsigned bpp; params_t(); }; params_t::params_t() : Q(1), X(256), Y(256), z0(0), w(3), name(0), format(FORMAT_NONE), bpp(8) { _f = Function[Q]; N = 3, M = 7; _c = 0.5; } #define MAX 10 class ostreambit { ostream& out; unsigned bb, k, w; public: ostreambit(ostream& os) : out(os), bb(0), k(0), w(0) {} void put_bits(unsigned bits, unsigned n) { bb <<= n; bb |= bits; k+=n; if (k>=8) { unsigned c = k>>3; k &= 7; unsigned b = bb>>k; out.write((const char*)&b,c); w+=c; } } void flush() { if (k>0) out.put(bb), w++; bb=0; k=0; } void put(char c) { out.put(c); w++; } unsigned bytes() { return w; } }; unsigned MapColor (complex_t &z, complex_t__value_type zz, unsigned bpp) { unsigned B = (1<>1; complex_t__value_type re = fabs(real(z)), im = fabs(imag(z)); complex_t__value_type m = min(re,im); return (m MAX*MAX) break; } osbit.put_bits(MapColor(z,zz,o.bpp),o.bpp); } osbit.flush(); while(osbit.bytes()&xalign) osbit.put(0); } } int ParseCommandLine (int argc, char *argv[], params_t &o) { for (int i = 1; i < argc; ++i) { const char *p = argv[i]; if (*p == '-') { ++p; char opt = *p++; int r = 0; float x,y; unsigned a,b; char c; stringstream s(p); switch (opt) { case 'R': if ((r = sscanf(p, "%u,%u%c", &a, &b, &c)) != 2) return 1; o.X = a, o.Y = b; break; case 'O': if ((r = sscanf(p, "%f,%f%c", &x, &y, &c)) != 2) return 1; o.z0 = complex_t(x,y); break; case 'W': if ((r = sscanf(p, "%f%c", &x, &c)) != 1) return 1; o.w = x; break; case 'F': if ((r = sscanf(p, "%u%c", &a, &c)) != 1) return 1; if (a >= DIMOF(Function)) return 1; o.Q = a, _f = Function[a]; break; case 'N': if ((r = sscanf(p, "%f,%f%c", &x, &y, &c)) != 2) return 1; N = complex_t(x,y); break; case 'M': if ((r = sscanf(p, "%f,%f%c", &x, &y, &c)) != 2) return 1; M = complex_t(x,y); break; case 'C': if ((r = sscanf(p, "%f,%f%c", &x, &y, &c)) != 2) return 1; _c = complex_t(x,y); break; case 'B': if ((r = sscanf(p, "%u%c", &a, &c)) != 1) return 1; o.bpp = a; break; default: return 1; } if (r == EOF) return 1; } else { if (o.name) return 1; else { const char *ext = strrchr(p,'.'); o.name = p; if (!ext) return 1; else if (!stricmp(ext,".bmp")) o.format = FORMAT_BMP; else if (!stricmp(ext,".tif")) o.format = FORMAT_TIFF; else return 1; } } } return 0; } void PrinUsage (const char *command) { cout << endl; cout << "Biomorph 1.00 - " << endl; cout << endl; cout << command << " [options] outfile.{bmp|tif}" << endl; cout << endl; cout << "Options:" << endl << endl; cout << " -Rh,v Resolution(Horiz,Vert) = 256,256" << endl; cout << " -Or,i Origin(Real,Imag) = (0,0)" << endl; cout << " -Ww Wide[Real] = 3" << endl; cout << " -Fn Function[0.." << DIMOF(Function)-1 << ']' << " = 1" << endl; for (int i=0; i ostream& operator<< (ostream& os, const T& t) { os.write((const char*)&t, sizeof(T)); return os;} typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; #pragma pack(push,1) struct BITMAPFILEHEADER { WORD bfType; DWORD bfSize; DWORD bfReserved; DWORD bfOffBits; BITMAPFILEHEADER(unsigned sz, unsigned off) : bfType('B'+'M'*256), bfSize(sz), bfReserved(0), bfOffBits(off) {} }; struct BITMAPINFOHEADER { DWORD biSize; DWORD biWidth; DWORD biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; DWORD biXPelsPerMeter; DWORD biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; BITMAPINFOHEADER(unsigned w, unsigned h, unsigned p, unsigned b) : biSize(sizeof(BITMAPINFOHEADER)), biWidth(w),biHeight(h), biPlanes(p),biBitCount(b) {} }; struct BITMAPCOREHEADER { DWORD bcSize; WORD bcWidth; WORD bcHeight; WORD bcPlanes; WORD bcBitCount; BITMAPCOREHEADER(unsigned w, unsigned h, unsigned p, unsigned b) : bcSize(sizeof(BITMAPCOREHEADER)), bcWidth(w),bcHeight(h), bcPlanes(p),bcBitCount(b) {} }; struct RGBTRIPLE { BYTE rgbtBlue; BYTE rgbtGreen; BYTE rgbtRed; RGBTRIPLE(BYTE r, BYTE g, BYTE b) : rgbtBlue(b), rgbtGreen(g), rgbtRed(r) {} }; struct RGBQUAD { BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; RGBQUAD(BYTE r, BYTE g, BYTE b, BYTE z=0) : rgbBlue(b), rgbGreen(g), rgbRed(r), rgbReserved(z) {} }; #pragma pack(pop) void BuildHeaderBMP (ostream& os, unsigned w, unsigned h, unsigned bpp, const string& comment) { const char *cptr = comment.c_str(); size_t clen = comment.size(); unsigned colors = 1 << bpp, amp = 1 << (8-bpp); unsigned hdrsz = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPCOREHEADER) + colors*sizeof(RGBTRIPLE); unsigned begin = hdrsz + clen + sizeof(_c_); unsigned llen = (w*bpp)/8; llen = (llen+3)&~3; os << BITMAPFILEHEADER(begin+llen*h, begin); os << BITMAPCOREHEADER(w, h, 1, bpp); unsigned i; /*for(i=1; i>3)*h); // StripByteCounts os << IFDEntry(282, TIFF_RATIONAL, 1, ofs); // XResolution os << IFDEntry(283, TIFF_RATIONAL, 1, ofs); // YResolution os << IFDEntry(284, TIFF_SHORT, 1, 1); // PlanarConfiguration os << IFDEntry(296, TIFF_SHORT, 1, 2); // ResolutionUnit (Inch) os << IFDEntry(315, TIFF_ASCII, sizeof(_c_), ofsArtist); // Artist os << IFDEntry(320, TIFF_SHORT, 3*colors, ofs+8); // ColorMap ofs = 0; os.write((const char*)&ofs,4); os << RATIONAL(72*0x1000000,0x1000000); unsigned i; uint16 c; n = 0; for(i=1; i