Skip to content
Permalink
Browse files

Merge pull request #929 from pygame/remove-pgopenutf8

Use SDL_RWops instead of pg_FopenUTF8.
  • Loading branch information...
illume committed Mar 24, 2019
2 parents f7675fc + 234e4bb commit a84b461f646b007a12c92c7157f595ec68a065a3
Showing with 29 additions and 147 deletions.
  1. +6 −10 src_c/_pygame.h
  2. +6 −110 src_c/base.c
  3. +17 −27 src_c/imageext.c
@@ -373,9 +373,9 @@ typedef struct {

#define PYGAMEAPI_BASE_FIRSTSLOT 0
#if IS_SDLv1
#define PYGAMEAPI_BASE_NUMSLOTS 20
#define PYGAMEAPI_BASE_NUMSLOTS 19
#else /* IS_SDLv2 */
#define PYGAMEAPI_BASE_NUMSLOTS 24
#define PYGAMEAPI_BASE_NUMSLOTS 23
#endif /* IS_SDLv2 */
#ifndef PYGAMEAPI_BASE_INTERNAL
#define pgExc_SDLError ((PyObject *)PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT])
@@ -445,22 +445,18 @@ typedef struct {
#define pgExc_BufferError \
((PyObject *)PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 18])

#define pg_FopenUTF8 \
(*(FILE* (*)(const char *, const char *)) \
PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 19])

#if IS_SDLv2
#define pg_GetDefaultWindow \
(*(SDL_Window * (*)(void)) PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 20])
(*(SDL_Window * (*)(void)) PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 19])

#define pg_SetDefaultWindow \
(*(void (*)(SDL_Window *))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 21])
(*(void (*)(SDL_Window *))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 20])

#define pg_GetDefaultWindowSurface \
(*(PyObject * (*)(void)) PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 22])
(*(PyObject * (*)(void)) PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 21])

#define pg_SetDefaultWindowSurface \
(*(void (*)(PyObject *))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 23])
(*(void (*)(PyObject *))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 22])

#endif /* IS_SDLv2 */

@@ -188,109 +188,6 @@ static void
pg_SetDefaultWindowSurface(PyObject *);
#endif /* IS_SDLv2 */


#include <errno.h>
#ifdef WIN32

static char*
_new_win_error_msg_utf8() {
/* must be free()'d by the caller */
size_t utf8_len;
char *utf8_buf = NULL;
size_t nwritten;
wchar_t* buffer = NULL;
DWORD numChars =
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0,
(wchar_t*)&buffer,
0, 0);
if (!numChars)
goto leave;
utf8_len =
WideCharToMultiByte(CP_UTF8, 0,
buffer, numChars,
NULL, 0,
NULL, NULL);
if (!utf8_len)
goto leave;
utf8_buf = malloc(utf8_len + 1);
if (!utf8_buf)
goto leave;
nwritten =
WideCharToMultiByte(CP_UTF8, 0,
buffer, numChars,
utf8_buf, utf8_len,
NULL, NULL);
if (!nwritten) {
free(utf8_buf);
utf8_buf = NULL;
goto leave;
}
utf8_buf[nwritten] = 0;

leave:
LocalFree(buffer);
return utf8_buf;
}

static FILE*
pg_FopenUTF8(const char *filename, const char *mode) {
FILE *fp = NULL;
static wchar_t modebuf[24];
size_t nameInputSize = strlen(filename) + 1;
size_t namebuf_chars = MultiByteToWideChar(CP_UTF8, 0, filename, nameInputSize, 0, 0);
wchar_t* namebuf;
if (namebuf_chars == 0)
return NULL;
namebuf = malloc(namebuf_chars * sizeof(wchar_t));
if (!namebuf)
goto leave;

if (MultiByteToWideChar(CP_UTF8, 0, filename, nameInputSize,
namebuf, namebuf_chars) == 0) {
char *utf8_buf = _new_win_error_msg_utf8();
if (utf8_buf) {
SDL_SetError("Cannot open file %s: %s.", filename, utf8_buf);
free(utf8_buf);
} else {
SDL_SetError("Cannot open file %s.", filename);
}
goto leave;
}
if (MultiByteToWideChar(CP_UTF8, 0, mode, -1,
modebuf, sizeof(modebuf) / sizeof(wchar_t)) == 0) {
char *utf8_buf = _new_win_error_msg_utf8();
if (utf8_buf) {
SDL_SetError("Cannot open file %s: %s.", filename, utf8_buf);
free(utf8_buf);
} else {
SDL_SetError("Cannot open file %s.", filename);
}
goto leave;
}

fp = _wfopen(namebuf, modebuf);
if (!fp)
SDL_SetError("Cannot open file %s. %s", filename, strerror(errno));

leave:
free(namebuf);
return fp;
}
#else /* !WIN32 */
static FILE*
pg_FopenUTF8(const char *filename, const char *mode) {
FILE *fp = fopen(filename, mode);
if (!fp)
SDL_SetError("Cannot open file %s. %s", filename, strerror(errno));
return fp;
}
#endif /* !WIN32 */

static int
pg_CheckSDLVersions(void) /*compare compiled to linked*/
{
@@ -2287,15 +2184,14 @@ MODINIT_DEFINE(base)
c_api[16] = pgBuffer_Release;
c_api[17] = pgDict_AsBuffer;
c_api[18] = pgExc_BufferError;
c_api[19] = pg_FopenUTF8;
#if IS_SDLv1
#define FILLED_SLOTS 20
#define FILLED_SLOTS 19
#else /* IS_SDLv2 */
c_api[20] = pg_GetDefaultWindow;
c_api[21] = pg_SetDefaultWindow;
c_api[22] = pg_GetDefaultWindowSurface;
c_api[23] = pg_SetDefaultWindowSurface;
#define FILLED_SLOTS 24
c_api[19] = pg_GetDefaultWindow;
c_api[20] = pg_SetDefaultWindow;
c_api[21] = pg_GetDefaultWindowSurface;
c_api[22] = pg_SetDefaultWindowSurface;
#define FILLED_SLOTS 23
#endif /* IS_SDLv2 */

#if PYGAMEAPI_BASE_NUMSLOTS != FILLED_SLOTS
@@ -104,7 +104,6 @@ image_load_ext(PyObject *self, PyObject *arg)
return NULL;
}

/*oencoded = pg_EncodeFilePath(obj, pgExc_SDLError);*/
oencoded = pg_EncodeString(obj, "UTF-8", NULL, pgExc_SDLError);
if (oencoded == NULL) {
return NULL;
@@ -149,7 +148,6 @@ image_load_ext(PyObject *self, PyObject *arg)
if (name == NULL) {
oname = PyObject_GetAttrString(obj, "name");
if (oname != NULL) {
/*oencoded = pg_EncodeFilePath(oname, NULL);*/
oencoded = pg_EncodeString(oname, "UTF-8", NULL, NULL);
Py_DECREF(oname);
if (oencoded == NULL) {
@@ -215,21 +213,17 @@ image_load_ext(PyObject *self, PyObject *arg)
static void
png_write_fn(png_structp png_ptr, png_bytep data, png_size_t length)
{
FILE *fp = (FILE *)png_get_io_ptr(png_ptr);
if (fwrite(data, 1, length, fp) != length) {
fclose(fp);
png_error(png_ptr, "Error while writing to the PNG file (fwrite)");
SDL_RWops *rwops = (SDL_RWops *)png_get_io_ptr(png_ptr);
if (SDL_RWwrite(rwops, data, 1, length) != length) {
SDL_RWclose(rwops);
png_error(png_ptr, "Error while writing to the PNG file (SDL_RWwrite)");
}
}

static void
png_flush_fn(png_structp png_ptr)
{
FILE *fp = (FILE *)png_get_io_ptr(png_ptr);
if (fflush(fp) == EOF) {
fclose(fp);
png_error(png_ptr, "Error while writing to PNG file (fflush)");
}
/* TODO: add SDL_RWflush() when it exists */
}

static int
@@ -238,10 +232,10 @@ write_png(const char *file_name, png_bytep *rows, int w, int h, int colortype,
{
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
FILE *fp;
SDL_RWops *rwops;
char *doing;

if (!(fp = pg_FopenUTF8(file_name, "wb"))) {
if (!(rwops = SDL_RWFromFile(file_name, "wb"))) {
return -1;
}

@@ -257,7 +251,7 @@ write_png(const char *file_name, png_bytep *rows, int w, int h, int colortype,
goto fail;

doing = "init IO";
png_set_write_fn(png_ptr, fp, png_write_fn, png_flush_fn);
png_set_write_fn(png_ptr, rwops, png_write_fn, png_flush_fn);

doing = "write header";
png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth, colortype,
@@ -274,7 +268,7 @@ write_png(const char *file_name, png_bytep *rows, int w, int h, int colortype,
png_write_end(png_ptr, NULL);

doing = "closing file";
if (0 != fclose(fp))
if (0 != SDL_RWclose(rwops))
goto fail;
png_destroy_write_struct(&png_ptr, &info_ptr);
return 0;
@@ -450,7 +444,7 @@ SavePNG(SDL_Surface *surface, const char *file)
typedef struct {
struct jpeg_destination_mgr pub; /* public fields */

FILE *outfile; /* target stream */
SDL_RWops *outfile; /* target stream */
JOCTET *buffer; /* start of buffer */
} j_outfile_mgr;

@@ -473,7 +467,7 @@ j_empty_output_buffer(j_compress_ptr cinfo)
{
j_outfile_mgr *dest = (j_outfile_mgr *)cinfo->dest;

if (fwrite(dest->buffer, 1, OUTPUT_BUF_SIZE, dest->outfile) !=
if (SDL_RWwrite(dest->outfile, dest->buffer, 1, OUTPUT_BUF_SIZE) !=
(size_t)OUTPUT_BUF_SIZE) {
ERREXIT(cinfo, JERR_FILE_WRITE);
}
@@ -491,19 +485,15 @@ j_term_destination(j_compress_ptr cinfo)

/* Write any data remaining in the buffer */
if (datacount > 0) {
if (fwrite(dest->buffer, 1, datacount, dest->outfile) != datacount) {
if (SDL_RWwrite(dest->outfile, dest->buffer, 1, datacount) != datacount) {
ERREXIT(cinfo, JERR_FILE_WRITE);
}
}
fflush(dest->outfile);
/* Make sure we wrote the output file OK */
if (ferror(dest->outfile)) {
ERREXIT(cinfo, JERR_FILE_WRITE);
}
/* TODO: add SDL_RWflush() when it exists */
}

static void
j_stdio_dest(j_compress_ptr cinfo, FILE *outfile)
j_stdio_dest(j_compress_ptr cinfo, SDL_RWops *outfile)
{
j_outfile_mgr *dest;

@@ -535,7 +525,7 @@ write_jpeg(const char *file_name, unsigned char **image_buffer,
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *outfile;
SDL_RWops *outfile;
JSAMPROW row_pointer[NUM_LINES_TO_WRITE];
int num_lines_to_write;
int i;
@@ -545,7 +535,7 @@ write_jpeg(const char *file_name, unsigned char **image_buffer,
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);

if (!(outfile = pg_FopenUTF8(file_name, "wb"))) {
if (!(outfile = SDL_RWFromFile(file_name, "wb"))) {
return -1;
}
j_stdio_dest(&cinfo, outfile);
@@ -579,7 +569,7 @@ write_jpeg(const char *file_name, unsigned char **image_buffer,
}

jpeg_finish_compress(&cinfo);
fclose(outfile);
SDL_RWclose(outfile);
jpeg_destroy_compress(&cinfo);
return 0;
}

0 comments on commit a84b461

Please sign in to comment.
You can’t perform that action at this time.