27
27
#include " CXX/Extensions.hxx"
28
28
#include " numpy/arrayobject.h"
29
29
#include " mplutils.h"
30
+ #include " numpy/npy_3kcompat.h"
30
31
31
32
// As reported in [3082058] build _png.so on aix
32
33
#ifdef _AIX
@@ -104,6 +105,7 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
104
105
105
106
FILE *fp = NULL ;
106
107
bool close_file = false ;
108
+ bool close_dup_file = false ;
107
109
Py::Object buffer_obj = Py::Object (args[0 ]);
108
110
PyObject* buffer = buffer_obj.ptr ();
109
111
if (!PyObject_CheckReadBuffer (buffer))
@@ -128,41 +130,33 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
128
130
}
129
131
130
132
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 ;
135
134
if (py_fileobj.isString ())
136
135
{
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 ();
143
138
}
144
139
close_file = true ;
145
140
}
146
- #if PY3K
147
- else if (fd != -1 )
141
+ else
148
142
{
149
- fp = fdopen (fd, " w " );
143
+ py_file = py_fileobj. ptr ( );
150
144
}
151
- # else
152
- else if (PyFile_CheckExact (py_fileobj. ptr ( )))
145
+
146
+ if ((fp = npy_PyFile_Dup (py_file, ( char *) " w " )))
153
147
{
154
- fp = PyFile_AsFile (py_fileobj. ptr ()) ;
148
+ close_dup_file = true ;
155
149
}
156
- #endif
157
150
else
158
151
{
159
152
PyObject* write_method = PyObject_GetAttrString (
160
- py_fileobj. ptr () , " write" );
153
+ py_file , " write" );
161
154
if (!(write_method && PyCallable_Check (write_method)))
162
155
{
163
156
Py_XDECREF (write_method);
164
157
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" );
166
160
}
167
161
Py_XDECREF (write_method);
168
162
}
@@ -205,7 +199,7 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
205
199
}
206
200
else
207
201
{
208
- png_set_write_fn (png_ptr, (void *)py_fileobj. ptr () ,
202
+ png_set_write_fn (png_ptr, (void *)py_file ,
209
203
&write_png_data, &flush_png_data);
210
204
}
211
205
png_set_IHDR (png_ptr, info_ptr,
@@ -241,9 +235,16 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
241
235
png_destroy_write_struct (&png_ptr, &info_ptr);
242
236
}
243
237
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)
245
245
{
246
- fclose (fp);
246
+ npy_PyFile_CloseFile (py_file);
247
+ Py_DECREF (py_file);
247
248
}
248
249
/* Changed calls to png_destroy_write_struct to follow
249
250
http://www.libpng.org/pub/png/libpng-manual.txt.
@@ -254,15 +255,15 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
254
255
255
256
png_destroy_write_struct (&png_ptr, &info_ptr);
256
257
delete [] row_pointers;
257
- #if PY3K
258
- if (fp)
258
+ if (close_dup_file)
259
259
{
260
- fflush ( fp);
260
+ npy_PyFile_DupClose (py_file, fp);
261
261
}
262
- # endif
263
- if (fp && close_file)
262
+
263
+ if (close_file)
264
264
{
265
- fclose (fp);
265
+ npy_PyFile_CloseFile (py_file);
266
+ Py_DECREF (py_file);
266
267
}
267
268
268
269
if (PyErr_Occurred ()) {
@@ -306,40 +307,32 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
306
307
png_byte header[8 ]; // 8 is the maximum size that can be checked
307
308
FILE* fp = NULL ;
308
309
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 ;
314
312
315
313
if (py_fileobj.isString ())
316
314
{
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 ();
323
317
}
324
318
close_file = true ;
319
+ } else {
320
+ py_file = py_fileobj.ptr ();
325
321
}
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" )))
332
324
{
333
- fp = PyFile_AsFile (py_fileobj. ptr ()) ;
325
+ close_dup_file = true ;
334
326
}
335
- #endif
336
327
else
337
328
{
338
- PyObject* read_method = PyObject_GetAttrString (py_fileobj. ptr () , " read" );
329
+ PyObject* read_method = PyObject_GetAttrString (py_file , " read" );
339
330
if (!(read_method && PyCallable_Check (read_method)))
340
331
{
341
332
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" );
343
336
}
344
337
Py_XDECREF (read_method);
345
338
}
@@ -354,7 +347,7 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
354
347
}
355
348
else
356
349
{
357
- _read_png_data (py_fileobj. ptr () , header, 8 );
350
+ _read_png_data (py_file , header, 8 );
358
351
}
359
352
if (png_sig_cmp (header, 0 , 8 ))
360
353
{
@@ -390,7 +383,7 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
390
383
}
391
384
else
392
385
{
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);
394
387
}
395
388
png_set_sig_bytes (png_ptr, 8 );
396
389
png_read_info (png_ptr, info_ptr);
@@ -572,10 +565,17 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
572
565
#else
573
566
png_destroy_read_struct (&png_ptr, &info_ptr, png_infopp_NULL);
574
567
#endif
568
+ if (close_dup_file)
569
+ {
570
+ npy_PyFile_DupClose (py_file, fp);
571
+ }
572
+
575
573
if (close_file)
576
574
{
577
- fclose (fp);
575
+ npy_PyFile_CloseFile (py_file);
576
+ Py_DECREF (py_file);
578
577
}
578
+
579
579
for (row = 0 ; row < height; row++)
580
580
{
581
581
delete [] row_pointers[row];
0 commit comments