1 /***************************************************************************
2  * export.cpp is part of Math Graphic Library
3  * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru>       *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU Lesser General Public License  as       *
7  *   published by the Free Software Foundation; either version 3 of the    *
8  *   License, or (at your option) any later version.                       *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU Lesser General Public     *
16  *   License along with this program; if not, write to the                 *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #include <time.h>
21 #include <stdarg.h>
22 
23 #if defined(WIN32) || defined(_MSC_VER) || defined(__BORLANDC__)
24 #include <windows.h>
25 #else
26 #include <unistd.h>
27 #endif
28 
29 #include "mgl2/canvas.h"
30 #include "mgl2/canvas_cf.h"
31 
32 #if MGL_HAVE_PNG
33 #include <png.h>
34 #endif
35 
36 #if MGL_HAVE_JPEG
37 extern "C" {
38 #include <jpeglib.h>
39 }
40 #endif
41 
42 #if MGL_HAVE_GIF
43 #include <gif_lib.h>
44 #endif
45 //-----------------------------------------------------------------------------
mgl_pnga_save(const char * fname,int w,int h,unsigned char ** p)46 int MGL_NO_EXPORT mgl_pnga_save(const char *fname, int w, int h, unsigned char **p)
47 {
48 #if MGL_HAVE_PNG
49 	bool fl = strcmp(fname,"-");
50 	FILE *fp = fl ? fopen(fname, "wb") : stdout;
51 	if (!fp)	return 1;
52 
53 	png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);
54 	if (png_ptr)
55 	{
56 		png_infop info_ptr = png_create_info_struct(png_ptr);
57 		if (info_ptr)
58 		{
59 			png_init_io(png_ptr, fp);
60 			png_set_filter(png_ptr, 0, PNG_ALL_FILTERS);
61 			png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
62 			png_set_IHDR(png_ptr, info_ptr, w, h, 8,
63 						PNG_COLOR_TYPE_RGB_ALPHA,
64 						PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
65 						PNG_FILTER_TYPE_DEFAULT);
66 			png_set_rows(png_ptr, info_ptr, p);
67 			png_write_png(png_ptr, info_ptr,  PNG_TRANSFORM_IDENTITY, 0);
68 //			png_write_end(png_ptr, info_ptr);
69 		}
70 		png_destroy_write_struct(&png_ptr, &info_ptr);
71 	}
72 	if(fl)	fclose(fp);
73 	return 0;
74 #else
75 	mgl_set_global_warn(_("PNG support was disabled. Please, enable it and rebuild MathGL."));
76 	return 1;
77 #endif
78 }
79 //-----------------------------------------------------------------------------
mgl_png_save(const char * fname,int w,int h,unsigned char ** p)80 int MGL_NO_EXPORT mgl_png_save(const char *fname, int w, int h, unsigned char **p)
81 {
82 #if MGL_HAVE_PNG
83 	bool fl = strcmp(fname,"-");
84 	FILE *fp = fl ? fopen(fname, "wb") : stdout;
85 	if (!fp)	return 1;
86 
87 	png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);
88 	if (png_ptr)
89 	{
90 		png_infop info_ptr = png_create_info_struct(png_ptr);
91 		if (info_ptr)
92 		{
93 			png_init_io(png_ptr, fp);
94 			png_set_filter(png_ptr, 0, PNG_ALL_FILTERS);
95 			png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
96 			png_set_IHDR(png_ptr, info_ptr, w, h, 8,
97 						PNG_COLOR_TYPE_RGB,
98 						PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
99 						PNG_FILTER_TYPE_DEFAULT);
100 			png_set_rows(png_ptr, info_ptr, p);
101 			png_write_png(png_ptr, info_ptr,  PNG_TRANSFORM_IDENTITY, 0);
102 //			png_write_end(png_ptr, info_ptr);
103 		}
104 		png_destroy_write_struct(&png_ptr, &info_ptr);
105 	}
106 	if(fl)	fclose(fp);
107 	return 0;
108 #else
109 	mgl_set_global_warn(_("PNG support was disabled. Please, enable it and rebuild MathGL."));
110 	return 1;
111 #endif
112 }
113 //-----------------------------------------------------------------------------
mgl_bmp_save(const char * fname,int w,int h,unsigned char ** p)114 int MGL_NO_EXPORT mgl_bmp_save(const char *fname, int w, int h, unsigned char **p)
115 {
116 	bool fl = strcmp(fname,"-");
117 	FILE *fp = fl ? fopen(fname, "wb") : stdout;
118 	if (!fp)	return 1;
119 
120 	char z[4] = {0,0,0,0};
121 	unsigned u = w*h*3 + 54;
122 	// BITMAPFILEHEADER
123 	fwrite("BM",2,1,fp);	fwrite(&u,4,1,fp);
124 	fwrite(z,4,1,fp);	u=54;	fwrite(&u,4,1,fp);
125 	// BITMAPINFOHEADER
126 	u=40;	fwrite(&u,4,1,fp);	fwrite(&w,4,1,fp);	fwrite(&h,4,1,fp);
127 	unsigned short pp=1;
128 	fwrite(&pp,2,1,fp);	pp=24;	fwrite(&pp,2,1,fp);	u = w*h*3;
129 	fwrite(z,4,1,fp);	fwrite(&u,4,1,fp);
130 	fwrite(z,4,1,fp);	fwrite(z,4,1,fp);
131 	fwrite(z,4,1,fp);	fwrite(z,4,1,fp);
132 	// image
133 	for(long i=h-1;i>=0;i--)	for(long j=0;j<w;j++)
134 	{
135 		const unsigned char *q = p[i]+3*j;
136 		fwrite(q+2,1,1,fp);
137 		fwrite(q+1,1,1,fp);
138 		fwrite(q+0,1,1,fp);
139 	}
140 	if(fl)	fclose(fp);
141 	return 0;
142 }
143 //-----------------------------------------------------------------------------
mgl_tga_save(const char * fname,int w,int h,unsigned char ** p)144 int MGL_NO_EXPORT mgl_tga_save(const char *fname, int w, int h, unsigned char **p)
145 {
146 	bool fl = strcmp(fname,"-");
147 	FILE *fp = fl ? fopen(fname, "wb") : stdout;
148 	if (!fp)	return 1;
149 	// header
150 	char head[14]={0,0,2, 0,0,0,0,0, 0,0,0,0, 32,0};
151 	fwrite(head,12,1,fp);
152 	fwrite(&w,2,1,fp);	fwrite(&h,2,1,fp);
153 	fwrite(head+12,2,1,fp);
154 	// image
155 	for(long i=h-1;i>=0;i--)	for(long j=0;j<w;j++)
156 	{
157 		const unsigned char *q = p[i]+4*j;
158 		fwrite(q+2,1,1,fp);
159 		fwrite(q+1,1,1,fp);
160 		fwrite(q+0,1,1,fp);
161 		fwrite(q+3,1,1,fp);
162 	}
163 	if(fl)	fclose(fp);
164 	return 0;
165 }
166 //-----------------------------------------------------------------------------
mgl_jpeg_save(const char * fname,int w,int h,unsigned char ** p)167 int MGL_NO_EXPORT mgl_jpeg_save(const char *fname, int w, int h, unsigned char **p)
168 {
169 #if MGL_HAVE_JPEG
170 	struct jpeg_compress_struct cinfo;
171 	struct jpeg_error_mgr jerr;
172 
173 	bool fl = strcmp(fname,"-");
174 	FILE *fp = fl ? fopen(fname, "wb") : stdout;
175 	if (!fp)	return 1;
176 
177 	cinfo.err = jpeg_std_error(&jerr);
178 	jpeg_create_compress(&cinfo);
179 	jpeg_stdio_dest(&cinfo, fp);
180 	cinfo.image_width = w;
181 	cinfo.image_height = h;
182 	cinfo.input_components = 3;
183 	cinfo.in_color_space = JCS_RGB;
184 	jpeg_set_defaults(&cinfo);
185 	jpeg_start_compress(&cinfo, TRUE);
186 	jpeg_write_scanlines(&cinfo, p, h);
187 	jpeg_finish_compress(&cinfo);
188 	jpeg_destroy_compress(&cinfo);
189 	if(fl)	fclose(fp);
190 	return 0;
191 #else
192 	mgl_set_global_warn(_("JPEG support was disabled. Please, enable it and rebuild MathGL."));
193 	return 1;
194 #endif
195 }
196 //-----------------------------------------------------------------------------
mgl_printf(void * fp,bool gz,const char * str,...)197 void MGL_NO_EXPORT mgl_printf(void *fp, bool gz, const char *str, ...)	// NOTE This function is not thread-safe
198 {
199 	static char buf[1024];
200 	va_list lst;
201 	va_start(lst,str);
202 	vsnprintf(buf,1023,str,lst);	buf[1023]=0;
203 	va_end(lst);
204 	if(gz)	gzprintf((gzFile)fp, "%s", buf);
205 	else	fprintf((FILE *)fp, "%s", buf);
206 }
207 //---------------------------------------------------------------------------
mgl_sprintf(const char * str,...)208 std::string MGL_NO_EXPORT mgl_sprintf(const char *str, ...)
209 {
210 	char *buf=new char[1024];
211 	va_list lst;
212 	va_start(lst,str);
213 	vsnprintf(buf,1023,str,lst);	buf[1023]=0;
214 	va_end(lst);
215 	std::string res = buf;	delete []buf;
216 	return res;
217 }
218 //---------------------------------------------------------------------------
mgl_bps_save(const char * fname,int w,int h,unsigned char ** p)219 int MGL_NO_EXPORT mgl_bps_save(const char *fname, int w, int h, unsigned char **p)
220 {
221 	time_t now;	time(&now);
222 	bool gz = fname[strlen(fname)-1]=='z';
223 
224 	void *fp;
225 	if(!strcmp(fname,"-"))	fp = stdout;		// allow to write in stdout
226 	else
227 	{
228 		fp = gz ? (void*)gzopen(fname,"wt") : (void*)fopen(fname,"wt");
229 		if(gz)
230 		{
231 			unsigned len = strlen(fname), pos=0;
232 			char *buf = new char[len+4];
233 			memcpy(buf,fname,len);
234 			if(buf[len-3]=='.')	pos = len-2;
235 			else if(buf[len-2]=='.')	pos = len-1;
236 			else	{	buf[len-1]='.';	pos = len;	}
237 			if(pos)	{	buf[pos]=buf[pos+1]='b';	buf[pos+2]=0;	}
238 			FILE *fb = fopen(buf,"w");
239 			fprintf(fb, "%%%%BoundingBox: 0 0 %d %d\n", w, h);
240 			fclose(fb);	delete []buf;
241 		}
242 	}
243 	mgl_printf(fp, gz, "%%!PS-Adobe-3.0 EPSF-3.0\n%%%%BoundingBox: 0 0 %d %d\n",w,h);
244 	mgl_printf(fp, gz, "%%%%Created by MathGL library\n%%%%Title: %s\n", fname);
245 	mgl_printf(fp, gz, "%%%%CreationDate: %s\n",ctime(&now));
246 	mgl_printf(fp, gz, "%d %d 8 [1 0 0 1 0 0] {currentfile %d string readhexstring pop} false 3 colorimage\n",
247 			w,h,w*h/40);
248 	for(long j=0;j<h;j++)	for(long i=0;i<w;i++)
249 	{
250 		if((i+w*j)%40==0 && i+j>0)	mgl_printf(fp, gz, "\n");
251 		long jj=h-1-j;
252 		mgl_printf(fp, gz, "%02x%02x%02x",p[jj][3*i],p[jj][3*i+1],p[jj][3*i+2]);
253 	}
254 	mgl_printf(fp, gz, "\n\nshowpage\n%%%%EOF\n");
255 	if(strcmp(fname,"-"))	{	if(gz)	gzclose((gzFile)fp);	else	fclose((FILE *)fp);	}
256 	return 0;
257 }
258 //-----------------------------------------------------------------------------
mgl_gif_save(const char * fname,int w,int h,unsigned char ** l)259 int MGL_NO_EXPORT mgl_gif_save(const char *fname, int w, int h, unsigned char **l)
260 {
261 #if MGL_HAVE_GIF
262 #if GIFLIB_MAJOR>=5
263 	GifFileType *fg = EGifOpenFileName(fname, 0, 0);
264 #else
265 	GifFileType *fg = EGifOpenFileName(fname, 0);
266 #endif
267 	// define colormap
268 	GifColorType col[256];
269 	memset(col,0,256*sizeof(GifColorType));
270 	for(int i=0;i<6;i++)	for(int j=0;j<6;j++)	for(int k=0;k<6;k++)
271 	{
272 		long m = i+6*(j+6*k);		// part 1
273 		col[m].Red = 51*i;
274 		col[m].Green=51*j;
275 		col[m].Blue =51*k;
276 	}
277 	// write header
278 #if GIFLIB_MAJOR>=5
279 	ColorMapObject *gmap = GifMakeMapObject(256, col);
280 	EGifPutScreenDesc(fg, w, h, 256,0,gmap);
281 	GifFreeMapObject(gmap);
282 #else
283 	ColorMapObject *gmap = MakeMapObject(256, col);
284 	EGifPutScreenDesc(fg, w, h, 256,0,gmap);
285 	FreeMapObject(gmap);
286 #endif
287 	// write frame
288 	EGifPutImageDesc(fg, 0, 0, w, h, 0, 0);
289 	GifPixelType *line = new GifPixelType[w*h];
290 	for(long m=0;m<w*h;m++)
291 	{
292 		long ii = 3*(m%w), k = m/w;
293 		int i = (l[k][ii]+25)/51;
294 		int j = (l[k][ii+1]+25)/51;
295 		k = (l[k][ii+2]+25)/51;
296 		line[m] = i+6*(j+6*k);
297 	}
298 	EGifPutLine(fg, line, w*h);
299 #if GIFLIB_MAJOR>5 || (GIFLIB_MAJOR==5 && GIFLIB_MINOR>0)
300 	EGifCloseFile(fg,0);
301 #else
302 	EGifCloseFile(fg);
303 #endif
304 	delete []line;	return 0;
305 #else
306 	mgl_set_global_warn(_("GIF support was disabled. Please, enable it and rebuild MathGL."));
307 	return 1;
308 #endif
309 }
310 //-----------------------------------------------------------------------------
311 //
312 //		Save animation
313 //
314 //-----------------------------------------------------------------------------
StartGIF(const char * fname,int ms)315 void mglCanvas::StartGIF(const char *fname, int ms)
316 {
317 #if MGL_HAVE_GIF
318 	std::string fn=fname;
319 	if(fn.empty())	{	fn=PlotId+".gif";	fname = fn.c_str();	}
320 #if GIFLIB_MAJOR>5 || (GIFLIB_MAJOR==5 && GIFLIB_MINOR>0)
321 	if(gif)	EGifCloseFile(gif,0);
322 #else
323 	if(gif)	EGifCloseFile(gif);
324 #endif
325 #if GIFLIB_MAJOR>=5
326 	gif = EGifOpenFileName(fname, 0, 0);
327 	EGifSetGifVersion(gif,true);
328 #else
329 	EGifSetGifVersion("89a");
330 	gif = EGifOpenFileName(fname, 0);
331 #endif
332 	// get picture sizes
333 	// NOTE: you shouldn't call SetSize() after StartGIF() !!!
334 	long width, height;
335 	unsigned char *f=0, **l=GetRGBLines(width, height, f);
336 	if(f)	free(f);
337 	if(l)	free(l);
338 	// define colormap
339 	GifColorType col[256];
340 	memset(col,0,256*sizeof(GifColorType));
341 	for(int i=0;i<6;i++)	for(int j=0;j<6;j++)	for(int k=0;k<6;k++)
342 	{
343 		long m = i+6*(j+6*k);		// part 1
344 		col[m].Red = 51*i;
345 		col[m].Green=51*j;
346 		col[m].Blue =51*k;
347 	}
348 	// write header
349 #if GIFLIB_MAJOR>=5
350 	ColorMapObject *gmap = GifMakeMapObject(256, col);
351 	EGifPutScreenDesc(gif, width, height, 256,0,gmap);
352 	GifFreeMapObject(gmap);
353 #else
354 	ColorMapObject *gmap = MakeMapObject(256, col);
355 	EGifPutScreenDesc(gif, width, height, 256,0,gmap);
356 	FreeMapObject(gmap);
357 #endif
358 	// put animation parameters
359 	ms /= 10;
360 	unsigned char ext1[11] = {0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30};
361 	unsigned char ext2[9] = {0x08, (unsigned char)(ms%256), (unsigned char)(ms/256), 0xff};
362 	unsigned char ext3[3] = {0x01, 0xff, 0xff};
363 #if GIFLIB_MAJOR>=5
364 	EGifPutExtensionLeader(gif,0xff);
365 	EGifPutExtensionBlock(gif,11,ext1);
366 	EGifPutExtensionBlock(gif,3,ext3);
367 	EGifPutExtensionTrailer(gif);
368 	EGifPutExtension(gif,0xf9,4,ext2);
369 #else
370 	EGifPutExtensionFirst(gif,0xff,11,ext1);
371 	EGifPutExtensionLast(gif,0xff,3,ext3);
372 	EGifPutExtension(gif,0xf9,4,ext2);
373 #endif
374 #else
375 	mgl_set_global_warn(_("GIF support was disabled. Please, enable it and rebuild MathGL."));
376 #endif
377 }
378 //-----------------------------------------------------------------------------
CloseGIF()379 void mglCanvas::CloseGIF()
380 {
381 #if MGL_HAVE_GIF
382 #if GIFLIB_MAJOR>5 || (GIFLIB_MAJOR==5 && GIFLIB_MINOR>0)
383 	if(gif)	EGifCloseFile(gif,0);
384 #else
385 	if(gif)	EGifCloseFile(gif);
386 #endif
387 #else
388 	mgl_set_global_warn(_("GIF support was disabled. Please, enable it and rebuild MathGL."));
389 #endif
390 	gif = 0;
391 }
392 //-----------------------------------------------------------------------------
NewFrame()393 int mglCanvas::NewFrame()
394 {
395 	Clf();	Identity();	CurFrameId++;
396 	return CurFrameId-1;
397 }
398 //-----------------------------------------------------------------------------
EndFrame()399 void mglCanvas::EndFrame()
400 {
401 	Finish();
402 	if(get(MGL_VECT_FRAME))	PushDrwDat();
403 #if MGL_HAVE_GIF
404 	if(!gif)	return;
405 	long width, height, n;
406 	unsigned char *f=0, **l=GetRGBLines(width, height, f);
407 	n = width*height;
408 	if(!l)	return;
409 	EGifPutImageDesc(gif, 0, 0, width, height, 0, 0);
410 	GifPixelType *line = new GifPixelType[n];
411 	for(long m=0;m<n;m++)
412 	{
413 		long ii = 3*(m%width), k = m/width;
414 		int i = (l[k][ii]+25)/51;
415 		int j = (l[k][ii+1]+25)/51;
416 		k = (l[k][ii+2]+25)/51;
417 		line[m] = i+6*(j+6*k);
418 	}
419 	EGifPutLine(gif, line, n);
420 	delete []line;	free(l);
421 	if(f)	free(f);
422 #endif
423 }
424 //-----------------------------------------------------------------------------
DelFrame(long i)425 void mglCanvas::DelFrame(long i)
426 {
427 #if MGL_HAVE_PTHREAD
428 	pthread_mutex_lock(&mutexDrw);
429 	if(get(MGL_VECT_FRAME))	DrwDat.erase(DrwDat.begin()+i);
430 	pthread_mutex_unlock(&mutexDrw);
431 #else
432 #pragma omp critical(drw)
433 	if(get(MGL_VECT_FRAME))	DrwDat.erase(DrwDat.begin()+i);
434 #endif
435 	CurFrameId--;
436 }
437 //-----------------------------------------------------------------------------
438 #undef _GR_
439 #define _GR_	((mglCanvas *)(*gr))
440 #define _Gr_	((mglCanvas *)(gr))
441 //-----------------------------------------------------------------------------
mgl_write_png(HMGL gr,const char * fname,const char *)442 void MGL_EXPORT mgl_write_png(HMGL gr, const char *fname,const char *)
443 {
444 	long w,h;	unsigned char *f=0, **p=0;
445 	p =_Gr_->GetRGBLines(w,h,f,true);
446 	if(p)
447 	{
448 		std::string fn=fname;
449 		if(fn.empty())	{	fn=gr->PlotId+".png";	fname = fn.c_str();	}
450 		if(mgl_pnga_save(fname,w,h,p))	gr->SetWarn(mglWarnOpen,fname);
451 		free(p);	if(f)	free(f);
452 	}
453 }
mgl_write_png_(uintptr_t * gr,const char * fname,const char * descr,int l,int n)454 void MGL_EXPORT mgl_write_png_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)
455 {	char *s=new char[l+1];	memcpy(s,fname,l);	s[l]=0;
456 	char *f=new char[n+1];	memcpy(f,descr,n);	f[n]=0;
457 	mgl_write_png(_GR_,s,f);	delete []s;		delete []f;	}
458 //-----------------------------------------------------------------------------
mgl_write_png_solid(HMGL gr,const char * fname,const char *)459 void MGL_EXPORT mgl_write_png_solid(HMGL gr, const char *fname,const char *)
460 {
461 	long w,h;	unsigned char *f=0, **p=0;
462 	p =_Gr_->GetRGBLines(w,h,f);
463 	if(p)
464 	{
465 		std::string fn=fname;
466 		if(fn.empty())	{	fn=gr->PlotId+".png";	fname = fn.c_str();	}
467 		if(mgl_png_save(fname,w,h,p))	gr->SetWarn(mglWarnOpen,fname);
468 		free(p);	if(f)	free(f);
469 	}
470 }
mgl_write_png_solid_(uintptr_t * gr,const char * fname,const char * descr,int l,int n)471 void MGL_EXPORT mgl_write_png_solid_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)
472 {	char *s=new char[l+1];	memcpy(s,fname,l);	s[l]=0;
473 	char *f=new char[n+1];	memcpy(f,descr,n);	f[n]=0;
474 	mgl_write_png_solid(_GR_,s,f);	delete []s;		delete []f;	}
475 //-----------------------------------------------------------------------------
mgl_write_jpg(HMGL gr,const char * fname,const char *)476 void MGL_EXPORT mgl_write_jpg(HMGL gr, const char *fname,const char *)
477 {
478 	long w,h;	unsigned char *f=0, **p=0;
479 	p =_Gr_->GetRGBLines(w,h,f);
480 	if(p)
481 	{
482 		std::string fn=fname;
483 		if(fn.empty())	{	fn=gr->PlotId+".jpg";	fname = fn.c_str();	}
484 		if(mgl_jpeg_save(fname,w,h,p))	gr->SetWarn(mglWarnOpen,fname);
485 		free(p);	if(f)	free(f);
486 	}
487 }
mgl_write_jpg_(uintptr_t * gr,const char * fname,const char * descr,int l,int n)488 void MGL_EXPORT mgl_write_jpg_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)
489 {	char *s=new char[l+1];	memcpy(s,fname,l);	s[l]=0;
490 	char *f=new char[n+1];	memcpy(f,descr,n);	f[n]=0;
491 	mgl_write_jpg(_GR_,s,f);	delete []s;		delete []f;	}
492 //-----------------------------------------------------------------------------
mgl_write_tga(HMGL gr,const char * fname,const char *)493 void MGL_EXPORT mgl_write_tga(HMGL gr, const char *fname,const char *)
494 {
495 	long w,h;	unsigned char *f=0, **p=0;
496 	p =_Gr_->GetRGBLines(w,h,f,true);
497 	if(p)
498 	{
499 		std::string fn=fname;
500 		if(fn.empty())	{	fn=gr->PlotId+".tga";	fname = fn.c_str();	}
501 		if(mgl_tga_save(fname,w,h,p))	gr->SetWarn(mglWarnOpen,fname);
502 		free(p);	if(f)	free(f);
503 	}
504 }
mgl_write_tga_(uintptr_t * gr,const char * fname,const char * descr,int l,int n)505 void MGL_EXPORT mgl_write_tga_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)
506 {	char *s=new char[l+1];	memcpy(s,fname,l);	s[l]=0;
507 	char *f=new char[n+1];	memcpy(f,descr,n);	f[n]=0;
508 	mgl_write_tga(_GR_,s,f);	delete []s;		delete []f;	}
509 //-----------------------------------------------------------------------------
mgl_write_bmp(HMGL gr,const char * fname,const char *)510 void MGL_EXPORT mgl_write_bmp(HMGL gr, const char *fname,const char *)
511 {
512 	long w,h;	unsigned char *f=0, **p=0;
513 	p =_Gr_->GetRGBLines(w,h,f);
514 	if(p)
515 	{
516 		std::string fn=fname;
517 		if(fn.empty())	{	fn=gr->PlotId+".bmp";	fname = fn.c_str();	}
518 		if(mgl_bmp_save(fname,w,h,p))	gr->SetWarn(mglWarnOpen,fname);
519 		free(p);	if(f)	free(f);
520 	}
521 }
mgl_write_bmp_(uintptr_t * gr,const char * fname,const char * descr,int l,int n)522 void MGL_EXPORT mgl_write_bmp_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)
523 {	char *s=new char[l+1];	memcpy(s,fname,l);	s[l]=0;
524 	char *f=new char[n+1];	memcpy(f,descr,n);	f[n]=0;
525 	mgl_write_bmp(_GR_,s,f);	delete []s;		delete []f;	}
526 //-----------------------------------------------------------------------------
mgl_write_bps(HMGL gr,const char * fname,const char *)527 void MGL_EXPORT mgl_write_bps(HMGL gr, const char *fname,const char *)
528 {
529 	long w,h;	unsigned char *f=0, **p=0;
530 	p =_Gr_->GetRGBLines(w,h,f);
531 	if(p)
532 	{
533 		std::string fn=fname;
534 		if(fn.empty())	{	fn=gr->PlotId+".eps";	fname = fn.c_str();	}
535 		if(mgl_bps_save(fname,w,h,p))	gr->SetWarn(mglWarnOpen,fname);
536 		free(p);	if(f)	free(f);
537 	}
538 }
mgl_write_bps_(uintptr_t * gr,const char * fname,const char * descr,int l,int n)539 void MGL_EXPORT mgl_write_bps_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)
540 {	char *s=new char[l+1];	memcpy(s,fname,l);	s[l]=0;
541 	char *f=new char[n+1];	memcpy(f,descr,n);	f[n]=0;
542 	mgl_write_bps(_GR_,s,f);	delete []s;		delete []f;	}
543 //-----------------------------------------------------------------------------
mgl_write_gif(HMGL gr,const char * fname,const char *)544 void MGL_EXPORT mgl_write_gif(HMGL gr, const char *fname,const char *)
545 {
546 	long w,h;	unsigned char *f=0, **p=0;
547 	p =_Gr_->GetRGBLines(w,h,f);
548 	if(p)
549 	{
550 		std::string fn=fname;
551 		if(fn.empty())	{	fn=gr->PlotId+".gif";	fname = fn.c_str();	}
552 		if(mgl_gif_save(fname,w,h,p))	gr->SetWarn(mglWarnOpen,fname);
553 		free(p);	if(f)	free(f);
554 	}
555 }
mgl_write_gif_(uintptr_t * gr,const char * fname,const char * descr,int l,int n)556 void MGL_EXPORT mgl_write_gif_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)
557 {	char *s=new char[l+1];	memcpy(s,fname,l);	s[l]=0;
558 	char *f=new char[n+1];	memcpy(f,descr,n);	f[n]=0;
559 	mgl_write_gif(_GR_,s,f);	delete []s;		delete []f;	}
560 //-----------------------------------------------------------------------------
mgl_start_gif(HMGL gr,const char * fname,int ms)561 void MGL_EXPORT mgl_start_gif(HMGL gr, const char *fname,int ms)
562 {	_Gr_->StartGIF(fname,ms);	}
mgl_start_gif_(uintptr_t * gr,const char * fname,int * ms,int l)563 void MGL_EXPORT mgl_start_gif_(uintptr_t *gr, const char *fname,int *ms,int l)
564 {	char *s=new char[l+1];	memcpy(s,fname,l);	s[l]=0;
565 	mgl_start_gif(_GR_,s,*ms);	delete []s;	}
566 //-----------------------------------------------------------------------------
mgl_close_gif(HMGL gr)567 void MGL_EXPORT mgl_close_gif(HMGL gr)			{	_Gr_->CloseGIF();	}
mgl_close_gif_(uintptr_t * gr)568 void MGL_EXPORT mgl_close_gif_(uintptr_t *gr)	{	mgl_close_gif(_GR_);	}
569 //-----------------------------------------------------------------------------
mgl_write_frame(HMGL gr,const char * fname,const char * descr)570 void MGL_EXPORT mgl_write_frame(HMGL gr, const char *fname,const char *descr)
571 {
572 	char buf[64];
573 	if(!fname || !fname[0])
574 	{	snprintf(buf,64,"%s%04d.jpg",_Gr_->PlotId.c_str(),_Gr_->GetNumFrame());	buf[63]=0;	fname = buf;	}
575 	int len=strlen(fname);
576 	if(!strcmp(fname+len-4,".jpg")) 	mgl_write_jpg(gr,fname,descr);
577 	else if(!strcmp(fname+len-5,".jpeg"))	mgl_write_jpg(gr,fname,descr);
578 	else if(!strcmp(fname+len-4,".prc")) 	mgl_write_prc(gr,fname,descr,1);
579 	else if(!strcmp(fname+len-4,".pdf")) 	mgl_write_prc(gr,fname,descr,1);
580 	else if(!strcmp(fname+len-4,".png")) 	mgl_write_png(gr,fname,descr);
581 	else if(!strcmp(fname+len-4,".eps")) 	mgl_write_eps(gr,fname,descr);
582 	else if(!strcmp(fname+len-5,".epsz"))	mgl_write_eps(gr,fname,descr);
583 	else if(!strcmp(fname+len-7,".eps.gz"))	mgl_write_eps(gr,fname,descr);
584 	else if(!strcmp(fname+len-4,".bps")) 	mgl_write_bps(gr,fname,descr);
585 	else if(!strcmp(fname+len-5,".bpsz"))	mgl_write_bps(gr,fname,descr);
586 	else if(!strcmp(fname+len-7,".bps.gz"))	mgl_write_bps(gr,fname,descr);
587 	else if(!strcmp(fname+len-4,".svg")) 	mgl_write_svg(gr,fname,descr);
588 	else if(!strcmp(fname+len-5,".svgz"))	mgl_write_svg(gr,fname,descr);
589 	else if(!strcmp(fname+len-7,".svg.gz"))	mgl_write_svg(gr,fname,descr);
590 	else if(!strcmp(fname+len-4,".gif")) 	mgl_write_gif(gr,fname,descr);
591 	else if(!strcmp(fname+len-4,".bmp")) 	mgl_write_bmp(gr,fname,descr);
592 	else if(!strcmp(fname+len-4,".tga")) 	mgl_write_tga(gr,fname,descr);
593 	else if(!strcmp(fname+len-5,".mgld"))	mgl_export_mgld(gr,fname,descr);
594 	else if(!strcmp(fname+len-5,".json"))	mgl_write_json(gr,fname,descr);
595 	else if(!strcmp(fname+len-6,".jsonz"))	mgl_write_json(gr,fname,descr);
596 	else if(!strcmp(fname+len-4,".obj")) 	mgl_write_obj(gr,fname,descr,1);
597 	else if(!strcmp(fname+len-4,".tex")) 	mgl_write_tex(gr,fname,descr);
598 	else if(!strcmp(fname+len-4,".xyz")) 	mgl_write_xyz(gr,fname,descr);
599 	else if(!strcmp(fname+len-4,".stl")) 	mgl_write_stl(gr,fname,descr);
600 	else if(!strcmp(fname+len-4,".off")) 	mgl_write_off(gr,fname,descr,0);
601 //	else if(!strcmp(fname+len-4,".x3d")) 	mgl_write_x3d(gr,fname,descr,1);
602 }
mgl_write_frame_(uintptr_t * gr,const char * fname,const char * descr,int l,int n)603 void MGL_EXPORT mgl_write_frame_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)
604 {	char *s=new char[l+1];	memcpy(s,fname,l);	s[l]=0;
605 	char *f=new char[n+1];	memcpy(f,descr,n);	f[n]=0;
606 	mgl_write_frame(_GR_,s,f);	delete []s;		delete []f;}
607 //-----------------------------------------------------------------------------
608 #ifdef WIN32
609 #include <io.h>
610 #include <direct.h>
611 #endif
mgl_show_image(HMGL gr,const char * viewer,int keep)612 void MGL_EXPORT mgl_show_image(HMGL gr, const char *viewer, int keep)
613 {
614 	static size_t counter=size_t(0xffffffff*mgl_rnd());
615 	char *fname = new char[256], *cmd = new char [288];
616 #if defined(_MSC_VER)
617 	snprintf(fname,128,"%s.png", tmpnam(NULL));
618 #else
619 	snprintf(fname,256,"%s/mathgl%lu.png", P_tmpdir, counter);
620 #endif
621 	fname[255]=0;	counter++;
622 	mgl_write_png_solid(gr,fname,"MathGL ShowImage file");
623 	if(!viewer || !viewer[0])
624 		viewer = MGL_DEF_VIEWER;
625 #ifdef WIN32
626 		if(keep)
627 		{
628 			snprintf(cmd,288,"%s %s &", viewer,fname);	cmd[287]=0;
629 			if(system(cmd)==-1)	printf(_("Error to call external viewer\n"));
630 			Sleep(2000);
631 			snprintf(cmd,288,"del %s", fname);
632 		}
633 		else	snprintf(cmd,288,"%s %s; del %s", viewer,fname,fname);
634 #else
635 		if(keep)
636 		{
637 			snprintf(cmd,288,"%s %s &", viewer,fname);	cmd[287]=0;
638 			if(system(cmd)==-1)	printf(_("Error to call external viewer\n"));
639 			sleep(2);
640 			snprintf(cmd,288,"rm %s", fname);
641 		}
642 		else	snprintf(cmd,288,"%s %s; rm %s", viewer,fname,fname);
643 #endif
644 		cmd[287] = 0;
645 		if(system(cmd)==-1)	printf(_("Error to call external viewer\n"));
646 		delete []cmd;	delete []fname;
647 }
mgl_show_image_(uintptr_t * gr,const char * viewer,int * keep,int l)648 void MGL_EXPORT mgl_show_image_(uintptr_t *gr, const char *viewer, int *keep, int l)
649 {	char *s=new char[l+1];	memcpy(s,viewer,l);	s[l]=0;
650 	mgl_show_image(_GR_,s,*keep);	delete []s;	}
651 //-----------------------------------------------------------------------------
652