@@ -1286,12 +1286,33 @@ RendererAgg::write_rgba(const Py::Tuple& args) {
12861286 _VERBOSE (" RendererAgg::write_rgba" );
12871287
12881288 args.verify_length (1 );
1289- std::string fname = Py::String (args[0 ]);
12901289
1291- std::ofstream of2 ( fname.c_str (), std::ios::binary|std::ios::out);
1292- for (size_t i=0 ; i<NUMBYTES; i++) {
1293- of2.write ((char *)&(pixBuffer[i]), sizeof (char ));
1290+ FILE *fp = NULL ;
1291+ bool close_file = false ;
1292+ Py::Object py_fileobj = Py::Object (args[0 ]);
1293+ if (py_fileobj.isString ()) {
1294+ std::string fileName = Py::String (py_fileobj);
1295+ const char *file_name = fileName.c_str ();
1296+ if ((fp = fopen (file_name, " wb" )) == NULL )
1297+ throw Py::RuntimeError ( Printf (" Could not open file %s" , file_name).str () );
1298+ fwrite (pixBuffer, 1 , NUMBYTES, fp);
1299+ close_file = true ;
1300+ fclose (fp);
1301+ } else if (PyFile_CheckExact (py_fileobj.ptr ())) {
1302+ fp = PyFile_AsFile (py_fileobj.ptr ());
1303+ fwrite (pixBuffer, 1 , NUMBYTES, fp);
1304+ } else {
1305+ PyObject* write_method = PyObject_GetAttrString (py_fileobj.ptr (), " write" );
1306+ if (!(write_method && PyCallable_Check (write_method))) {
1307+ Py_XDECREF (write_method);
1308+ throw Py::TypeError (" Object does not appear to be a 8-bit string path or a Python file-like object" );
1309+ }
1310+
1311+ PyObject_CallFunction (write_method, " s#" , pixBuffer, NUMBYTES);
1312+
1313+ Py_XDECREF (write_method);
12941314 }
1315+
12951316 return Py::Object ();
12961317}
12971318
@@ -1326,18 +1347,22 @@ RendererAgg::write_png(const Py::Tuple& args)
13261347 args.verify_length (1 , 2 );
13271348
13281349 FILE *fp = NULL ;
1350+ bool close_file = false ;
13291351 Py::Object py_fileobj = Py::Object (args[0 ]);
13301352 if (py_fileobj.isString ()) {
13311353 std::string fileName = Py::String (py_fileobj);
13321354 const char *file_name = fileName.c_str ();
13331355 if ((fp = fopen (file_name, " wb" )) == NULL )
13341356 throw Py::RuntimeError ( Printf (" Could not open file %s" , file_name).str () );
1357+ close_file = true ;
1358+ } else if (PyFile_CheckExact (py_fileobj.ptr ())) {
1359+ fp = PyFile_AsFile (py_fileobj.ptr ());
13351360 }
13361361 else {
13371362 PyObject* write_method = PyObject_GetAttrString (py_fileobj.ptr (), " write" );
13381363 if (!(write_method && PyCallable_Check (write_method))) {
13391364 Py_XDECREF (write_method);
1340- throw Py::TypeError (" Object does not appear to be a path or a Python file-like object" );
1365+ throw Py::TypeError (" Object does not appear to be a 8-bit string path or a Python file-like object" );
13411366 }
13421367 Py_XDECREF (write_method);
13431368 }
@@ -1406,15 +1431,15 @@ RendererAgg::write_png(const Py::Tuple& args)
14061431 */
14071432
14081433 } catch (...) {
1409- if (fp) fclose (fp);
1434+ if (fp && close_file ) fclose (fp);
14101435 delete [] row_pointers;
14111436 if (png_ptr && info_ptr) png_destroy_write_struct (&png_ptr, &info_ptr);
14121437 throw ;
14131438 }
14141439
14151440 png_destroy_write_struct (&png_ptr, &info_ptr);
14161441 delete [] row_pointers;
1417- if (fp) fclose (fp);
1442+ if (fp && close_file ) fclose (fp);
14181443
14191444 return Py::Object ();
14201445}
0 commit comments