2727#include " CXX/Extensions.hxx"
2828#include " numpy/arrayobject.h"
2929#include " mplutils.h"
30+ #include " numpy/npy_3kcompat.h"
3031
3132// As reported in [3082058] build _png.so on aix
3233#ifdef _AIX
@@ -104,6 +105,7 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
104105
105106 FILE *fp = NULL ;
106107 bool close_file = false ;
108+ bool close_dup_file = false ;
107109 Py::Object buffer_obj = Py::Object (args[0 ]);
108110 PyObject* buffer = buffer_obj.ptr ();
109111 if (!PyObject_CheckReadBuffer (buffer))
@@ -128,41 +130,33 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
128130 }
129131
130132 Py::Object py_fileobj = Py::Object (args[3 ]);
131- #if PY3K
132- int fd = PyObject_AsFileDescriptor (py_fileobj.ptr ());
133- PyErr_Clear ();
134- #endif
133+ PyObject* py_file = NULL ;
135134 if (py_fileobj.isString ())
136135 {
137- std::string fileName = Py::String (py_fileobj);
138- const char *file_name = fileName.c_str ();
139- if ((fp = fopen (file_name, " wb" )) == NULL )
140- {
141- throw Py::RuntimeError (
142- Printf (" Could not open file %s" , file_name).str ());
136+ if ((py_file = npy_PyFile_OpenFile (py_file, (char *)" w" )) == NULL ) {
137+ throw Py::Exception ();
143138 }
144139 close_file = true ;
145140 }
146- #if PY3K
147- else if (fd != -1 )
141+ else
148142 {
149- fp = fdopen (fd, " w " );
143+ py_file = py_fileobj. ptr ( );
150144 }
151- # else
152- else if (PyFile_CheckExact (py_fileobj. ptr ( )))
145+
146+ if ((fp = npy_PyFile_Dup (py_file, ( char *) " w " )))
153147 {
154- fp = PyFile_AsFile (py_fileobj. ptr ()) ;
148+ close_dup_file = true ;
155149 }
156- #endif
157150 else
158151 {
159152 PyObject* write_method = PyObject_GetAttrString (
160- py_fileobj. ptr () , " write" );
153+ py_file , " write" );
161154 if (!(write_method && PyCallable_Check (write_method)))
162155 {
163156 Py_XDECREF (write_method);
164157 throw Py::TypeError (
165- " Object does not appear to be a 8-bit string path or a Python file-like object" );
158+ " Object does not appear to be a 8-bit string path or "
159+ " a Python file-like object" );
166160 }
167161 Py_XDECREF (write_method);
168162 }
@@ -205,7 +199,7 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
205199 }
206200 else
207201 {
208- png_set_write_fn (png_ptr, (void *)py_fileobj. ptr () ,
202+ png_set_write_fn (png_ptr, (void *)py_file ,
209203 &write_png_data, &flush_png_data);
210204 }
211205 png_set_IHDR (png_ptr, info_ptr,
@@ -241,9 +235,16 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
241235 png_destroy_write_struct (&png_ptr, &info_ptr);
242236 }
243237 delete [] row_pointers;
244- if (fp && close_file)
238+
239+ if (close_dup_file)
240+ {
241+ npy_PyFile_DupClose (py_file, fp);
242+ }
243+
244+ if (close_file)
245245 {
246- fclose (fp);
246+ npy_PyFile_CloseFile (py_file);
247+ Py_DECREF (py_file);
247248 }
248249 /* Changed calls to png_destroy_write_struct to follow
249250 http://www.libpng.org/pub/png/libpng-manual.txt.
@@ -254,15 +255,15 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
254255
255256 png_destroy_write_struct (&png_ptr, &info_ptr);
256257 delete [] row_pointers;
257- #if PY3K
258- if (fp)
258+ if (close_dup_file)
259259 {
260- fflush ( fp);
260+ npy_PyFile_DupClose (py_file, fp);
261261 }
262- # endif
263- if (fp && close_file)
262+
263+ if (close_file)
264264 {
265- fclose (fp);
265+ npy_PyFile_CloseFile (py_file);
266+ Py_DECREF (py_file);
266267 }
267268
268269 if (PyErr_Occurred ()) {
@@ -306,40 +307,32 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
306307 png_byte header[8 ]; // 8 is the maximum size that can be checked
307308 FILE* fp = NULL ;
308309 bool close_file = false ;
309-
310- #if PY3K
311- int fd = PyObject_AsFileDescriptor (py_fileobj.ptr ());
312- PyErr_Clear ();
313- #endif
310+ bool close_dup_file = false ;
311+ PyObject *py_file = NULL ;
314312
315313 if (py_fileobj.isString ())
316314 {
317- std::string fileName = Py::String (py_fileobj);
318- const char *file_name = fileName.c_str ();
319- if ((fp = fopen (file_name, " rb" )) == NULL )
320- {
321- throw Py::RuntimeError (
322- Printf (" Could not open file %s for reading" , file_name).str ());
315+ if ((py_file = npy_PyFile_OpenFile (py_fileobj.ptr (), (char *)" r" )) == NULL ) {
316+ throw Py::Exception ();
323317 }
324318 close_file = true ;
319+ } else {
320+ py_file = py_fileobj.ptr ();
325321 }
326- #if PY3K
327- else if (fd != -1 ) {
328- fp = fdopen (fd, " r" );
329- }
330- #else
331- else if (PyFile_CheckExact (py_fileobj.ptr ()))
322+
323+ if ((fp = npy_PyFile_Dup (py_file, " r" )))
332324 {
333- fp = PyFile_AsFile (py_fileobj. ptr ()) ;
325+ close_dup_file = true ;
334326 }
335- #endif
336327 else
337328 {
338- PyObject* read_method = PyObject_GetAttrString (py_fileobj. ptr () , " read" );
329+ PyObject* read_method = PyObject_GetAttrString (py_file , " read" );
339330 if (!(read_method && PyCallable_Check (read_method)))
340331 {
341332 Py_XDECREF (read_method);
342- throw Py::TypeError (" Object does not appear to be a 8-bit string path or a Python file-like object" );
333+ throw Py::TypeError (
334+ " Object does not appear to be a 8-bit string path or a Python "
335+ " file-like object" );
343336 }
344337 Py_XDECREF (read_method);
345338 }
@@ -354,7 +347,7 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
354347 }
355348 else
356349 {
357- _read_png_data (py_fileobj. ptr () , header, 8 );
350+ _read_png_data (py_file , header, 8 );
358351 }
359352 if (png_sig_cmp (header, 0 , 8 ))
360353 {
@@ -390,7 +383,7 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
390383 }
391384 else
392385 {
393- png_set_read_fn (png_ptr, (void *)py_fileobj. ptr () , &read_png_data);
386+ png_set_read_fn (png_ptr, (void *)py_file , &read_png_data);
394387 }
395388 png_set_sig_bytes (png_ptr, 8 );
396389 png_read_info (png_ptr, info_ptr);
@@ -572,10 +565,17 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
572565#else
573566 png_destroy_read_struct (&png_ptr, &info_ptr, png_infopp_NULL);
574567#endif
568+ if (close_dup_file)
569+ {
570+ npy_PyFile_DupClose (py_file, fp);
571+ }
572+
575573 if (close_file)
576574 {
577- fclose (fp);
575+ npy_PyFile_CloseFile (py_file);
576+ Py_DECREF (py_file);
578577 }
578+
579579 for (row = 0 ; row < height; row++)
580580 {
581581 delete [] row_pointers[row];
0 commit comments