27
27
#include " CXX/Extensions.hxx"
28
28
#include " numpy/arrayobject.h"
29
29
#include " mplutils.h"
30
+ #include " file_compat.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,34 @@ 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_fileobj.ptr (), (char *)" wb" )) == 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 *) " wb " )))
153
147
{
154
- fp = PyFile_AsFile (py_fileobj. ptr ()) ;
148
+ close_dup_file = true ;
155
149
}
156
- #endif
157
150
else
158
151
{
152
+ PyErr_Clear ();
159
153
PyObject* write_method = PyObject_GetAttrString (
160
- py_fileobj. ptr () , " write" );
154
+ py_file , " write" );
161
155
if (!(write_method && PyCallable_Check (write_method)))
162
156
{
163
157
Py_XDECREF (write_method);
164
158
throw Py::TypeError (
165
- " Object does not appear to be a 8-bit string path or a Python file-like object" );
159
+ " Object does not appear to be a 8-bit string path or "
160
+ " a Python file-like object" );
166
161
}
167
162
Py_XDECREF (write_method);
168
163
}
@@ -205,7 +200,7 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
205
200
}
206
201
else
207
202
{
208
- png_set_write_fn (png_ptr, (void *)py_fileobj. ptr () ,
203
+ png_set_write_fn (png_ptr, (void *)py_file ,
209
204
&write_png_data, &flush_png_data);
210
205
}
211
206
png_set_IHDR (png_ptr, info_ptr,
@@ -241,9 +236,16 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
241
236
png_destroy_write_struct (&png_ptr, &info_ptr);
242
237
}
243
238
delete [] row_pointers;
244
- if (fp && close_file)
239
+
240
+ if (close_dup_file)
241
+ {
242
+ npy_PyFile_DupClose (py_file, fp);
243
+ }
244
+
245
+ if (close_file)
245
246
{
246
- fclose (fp);
247
+ npy_PyFile_CloseFile (py_file);
248
+ Py_DECREF (py_file);
247
249
}
248
250
/* Changed calls to png_destroy_write_struct to follow
249
251
http://www.libpng.org/pub/png/libpng-manual.txt.
@@ -254,15 +256,15 @@ Py::Object _png_module::write_png(const Py::Tuple& args)
254
256
255
257
png_destroy_write_struct (&png_ptr, &info_ptr);
256
258
delete [] row_pointers;
257
- #if PY3K
258
- if (fp)
259
+ if (close_dup_file)
259
260
{
260
- fflush ( fp);
261
+ npy_PyFile_DupClose (py_file, fp);
261
262
}
262
- # endif
263
- if (fp && close_file)
263
+
264
+ if (close_file)
264
265
{
265
- fclose (fp);
266
+ npy_PyFile_CloseFile (py_file);
267
+ Py_DECREF (py_file);
266
268
}
267
269
268
270
if (PyErr_Occurred ()) {
@@ -306,40 +308,33 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
306
308
png_byte header[8 ]; // 8 is the maximum size that can be checked
307
309
FILE* fp = NULL ;
308
310
bool close_file = false ;
309
-
310
- #if PY3K
311
- int fd = PyObject_AsFileDescriptor (py_fileobj.ptr ());
312
- PyErr_Clear ();
313
- #endif
311
+ bool close_dup_file = false ;
312
+ PyObject *py_file = NULL ;
314
313
315
314
if (py_fileobj.isString ())
316
315
{
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 ());
316
+ if ((py_file = npy_PyFile_OpenFile (py_fileobj.ptr (), (char *)" rb" )) == NULL ) {
317
+ throw Py::Exception ();
323
318
}
324
319
close_file = true ;
320
+ } else {
321
+ py_file = py_fileobj.ptr ();
325
322
}
326
- #if PY3K
327
- else if (fd != -1 ) {
328
- fp = fdopen (fd, " r" );
329
- }
330
- #else
331
- else if (PyFile_CheckExact (py_fileobj.ptr ()))
323
+
324
+ if ((fp = npy_PyFile_Dup (py_file, " rb" )))
332
325
{
333
- fp = PyFile_AsFile (py_fileobj. ptr ()) ;
326
+ close_dup_file = true ;
334
327
}
335
- #endif
336
328
else
337
329
{
338
- PyObject* read_method = PyObject_GetAttrString (py_fileobj.ptr (), " read" );
330
+ PyErr_Clear ();
331
+ PyObject* read_method = PyObject_GetAttrString (py_file, " read" );
339
332
if (!(read_method && PyCallable_Check (read_method)))
340
333
{
341
334
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" );
335
+ throw Py::TypeError (
336
+ " Object does not appear to be a 8-bit string path or a Python "
337
+ " file-like object" );
343
338
}
344
339
Py_XDECREF (read_method);
345
340
}
@@ -354,7 +349,7 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
354
349
}
355
350
else
356
351
{
357
- _read_png_data (py_fileobj. ptr () , header, 8 );
352
+ _read_png_data (py_file , header, 8 );
358
353
}
359
354
if (png_sig_cmp (header, 0 , 8 ))
360
355
{
@@ -390,7 +385,7 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
390
385
}
391
386
else
392
387
{
393
- png_set_read_fn (png_ptr, (void *)py_fileobj. ptr () , &read_png_data);
388
+ png_set_read_fn (png_ptr, (void *)py_file , &read_png_data);
394
389
}
395
390
png_set_sig_bytes (png_ptr, 8 );
396
391
png_read_info (png_ptr, info_ptr);
@@ -572,10 +567,17 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
572
567
#else
573
568
png_destroy_read_struct (&png_ptr, &info_ptr, png_infopp_NULL);
574
569
#endif
570
+ if (close_dup_file)
571
+ {
572
+ npy_PyFile_DupClose (py_file, fp);
573
+ }
574
+
575
575
if (close_file)
576
576
{
577
- fclose (fp);
577
+ npy_PyFile_CloseFile (py_file);
578
+ Py_DECREF (py_file);
578
579
}
580
+
579
581
for (row = 0 ; row < height; row++)
580
582
{
581
583
delete [] row_pointers[row];
0 commit comments