diff --git a/src/decode.c b/src/decode.c index 51d0aced2..1e9906ae7 100644 --- a/src/decode.c +++ b/src/decode.c @@ -293,7 +293,7 @@ static PyTypeObject ImagingDecoderType = { /* -------------------------------------------------------------------- */ int -get_unpacker(ImagingDecoderObject *decoder, const char *mode, const char *rawmode) { +get_unpacker(ImagingDecoderObject *decoder, const Mode *mode, const RawMode *rawmode) { int bits; ImagingShuffler unpack; @@ -463,12 +463,14 @@ PyObject * PyImaging_HexDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; - if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) { + char *mode_name, *rawmode_name; + if (!PyArg_ParseTuple(args, "ss", &mode_name, &rawmode_name)) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + decoder = PyImaging_DecoderNew(0); if (decoder == NULL) { return NULL; @@ -496,16 +498,19 @@ PyImaging_HexDecoderNew(PyObject *self, PyObject *args) { PyObject * PyImaging_LibTiffDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; char *compname; int fp; uint32_t ifdoffset; - if (!PyArg_ParseTuple(args, "sssiI", &mode, &rawmode, &compname, &fp, &ifdoffset)) { + if (!PyArg_ParseTuple(args, "sssiI", &mode_name, &rawmode_name, &compname, &fp, &ifdoffset)) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + TRACE(("new tiff decoder %s\n", compname)); decoder = PyImaging_DecoderNew(sizeof(TIFFSTATE)); @@ -538,12 +543,15 @@ PyObject * PyImaging_PackbitsDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; - if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) { + char *mode_name; + char *rawmode_name; + if (!PyArg_ParseTuple(args, "ss", &mode_name, &rawmode_name)) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + decoder = PyImaging_DecoderNew(0); if (decoder == NULL) { return NULL; @@ -572,7 +580,7 @@ PyImaging_PcdDecoderNew(PyObject *self, PyObject *args) { } /* Unpack from PhotoYCC to RGB */ - if (get_unpacker(decoder, "RGB", "YCC;P") < 0) { + if (get_unpacker(decoder, IMAGING_MODE_RGB, IMAGING_RAWMODE_YCC_P) < 0) { return NULL; } @@ -589,13 +597,15 @@ PyObject * PyImaging_PcxDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name, *rawmode_name; int stride; - if (!PyArg_ParseTuple(args, "ssi", &mode, &rawmode, &stride)) { + if (!PyArg_ParseTuple(args, "ssi", &mode_name, &rawmode_name, &stride)) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + decoder = PyImaging_DecoderNew(0); if (decoder == NULL) { return NULL; @@ -620,14 +630,16 @@ PyObject * PyImaging_RawDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name, *rawmode_name; int stride = 0; int ystep = 1; - if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &stride, &ystep)) { + if (!PyArg_ParseTuple(args, "ss|ii", &mode_name, &rawmode_name, &stride, &ystep)) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + decoder = PyImaging_DecoderNew(sizeof(RAWSTATE)); if (decoder == NULL) { return NULL; @@ -654,14 +666,16 @@ PyObject * PyImaging_SgiRleDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name, *rawmode_name; int ystep = 1; int bpc = 1; - if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &ystep, &bpc)) { + if (!PyArg_ParseTuple(args, "ss|ii", &mode_name, &rawmode_name, &ystep, &bpc)) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + decoder = PyImaging_DecoderNew(sizeof(SGISTATE)); if (decoder == NULL) { return NULL; @@ -688,12 +702,14 @@ PyObject * PyImaging_SunRleDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; - if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) { + char *mode_name, *rawmode_name; + if (!PyArg_ParseTuple(args, "ss", &mode_name, &rawmode_name)) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + decoder = PyImaging_DecoderNew(0); if (decoder == NULL) { return NULL; @@ -716,14 +732,16 @@ PyObject * PyImaging_TgaRleDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name, *rawmode_name; int ystep = 1; int depth = 8; - if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &ystep, &depth)) { + if (!PyArg_ParseTuple(args, "ss|ii", &mode_name, &rawmode_name, &ystep, &depth)) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + decoder = PyImaging_DecoderNew(0); if (decoder == NULL) { return NULL; @@ -754,7 +772,7 @@ PyImaging_XbmDecoderNew(PyObject *self, PyObject *args) { return NULL; } - if (get_unpacker(decoder, "1", "1;R") < 0) { + if (get_unpacker(decoder, IMAGING_MODE_1, IMAGING_RAWMODE_1_R) < 0) { return NULL; } @@ -775,13 +793,15 @@ PyObject * PyImaging_ZipDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name, *rawmode_name; int interlaced = 0; - if (!PyArg_ParseTuple(args, "ss|i", &mode, &rawmode, &interlaced)) { + if (!PyArg_ParseTuple(args, "ss|i", &mode_name, &rawmode_name, &interlaced)) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + decoder = PyImaging_DecoderNew(sizeof(ZIPSTATE)); if (decoder == NULL) { return NULL; @@ -825,16 +845,19 @@ PyObject * PyImaging_JpegDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; /* what we want from the decoder */ - char *jpegmode; /* what's in the file */ + char *mode_name; + char *rawmode_name; /* what we want from the decoder */ + char *jpegmode; /* what's in the file */ int scale = 1; int draft = 0; - if (!PyArg_ParseTuple(args, "ssz|ii", &mode, &rawmode, &jpegmode, &scale, &draft)) { + if (!PyArg_ParseTuple(args, "ssz|ii", &mode_name, &rawmode_name, &jpegmode, &scale, &draft)) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * rawmode = findRawMode(rawmode_name); + if (!jpegmode) { jpegmode = ""; } @@ -847,8 +870,8 @@ PyImaging_JpegDecoderNew(PyObject *self, PyObject *args) { // libjpeg-turbo supports different output formats. // We are choosing Pillow's native format (3 color bytes + 1 padding) // to avoid extra conversion in Unpack.c. - if (ImagingJpegUseJCSExtensions() && strcmp(rawmode, "RGB") == 0) { - rawmode = "RGBX"; + if (ImagingJpegUseJCSExtensions() && rawmode == IMAGING_RAWMODE_RGB) { + rawmode = IMAGING_RAWMODE_RGBX; } if (get_unpacker(decoder, mode, rawmode) < 0) { @@ -858,11 +881,13 @@ PyImaging_JpegDecoderNew(PyObject *self, PyObject *args) { decoder->decode = ImagingJpegDecode; decoder->cleanup = ImagingJpegDecodeCleanup; - strncpy(((JPEGSTATE *)decoder->state.context)->rawmode, rawmode, 8); - strncpy(((JPEGSTATE *)decoder->state.context)->jpegmode, jpegmode, 8); + JPEGSTATE *jpeg_decoder_state_context = (JPEGSTATE *)decoder->state.context; - ((JPEGSTATE *)decoder->state.context)->scale = scale; - ((JPEGSTATE *)decoder->state.context)->draft = draft; + jpeg_decoder_state_context->rawmode = rawmode; + strncpy(jpeg_decoder_state_context->jpegmode, jpegmode, 8); + + jpeg_decoder_state_context->scale = scale; + jpeg_decoder_state_context->draft = draft; return (PyObject *)decoder; } diff --git a/src/encode.c b/src/encode.c index 1a4cd489d..c8a5c463e 100644 --- a/src/encode.c +++ b/src/encode.c @@ -360,14 +360,19 @@ static PyTypeObject ImagingEncoderType = { /* -------------------------------------------------------------------- */ int -get_packer(ImagingEncoderObject *encoder, const char *mode, const char *rawmode) { +get_packer(ImagingEncoderObject *encoder, const Mode *mode, const RawMode *rawmode) { int bits; ImagingShuffler pack; pack = ImagingFindPacker(mode, rawmode, &bits); if (!pack) { Py_DECREF(encoder); - PyErr_Format(PyExc_ValueError, "No packer found from %s to %s", mode, rawmode); + PyErr_Format( + PyExc_ValueError, + "No packer found from %s to %s", + mode->name, + rawmode->name + ); return -1; } @@ -403,11 +408,11 @@ PyObject * PyImaging_GifEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t bits = 8; Py_ssize_t interlace = 0; - if (!PyArg_ParseTuple(args, "ss|nn", &mode, &rawmode, &bits, &interlace)) { + if (!PyArg_ParseTuple(args, "ss|nn", &mode_name, &rawmode_name, &bits, &interlace)) { return NULL; } @@ -416,6 +421,9 @@ PyImaging_GifEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { return NULL; } @@ -436,11 +444,11 @@ PyObject * PyImaging_PcxEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t bits = 8; - if (!PyArg_ParseTuple(args, "ss|n", &mode, &rawmode, &bits)) { + if (!PyArg_ParseTuple(args, "ss|n", &mode_name, &rawmode_name, &bits)) { return NULL; } @@ -449,6 +457,9 @@ PyImaging_PcxEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { return NULL; } @@ -466,12 +477,12 @@ PyObject * PyImaging_RawEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t stride = 0; Py_ssize_t ystep = 1; - if (!PyArg_ParseTuple(args, "ss|nn", &mode, &rawmode, &stride, &ystep)) { + if (!PyArg_ParseTuple(args, "ss|nn", &mode_name, &rawmode_name, &stride, &ystep)) { return NULL; } @@ -480,6 +491,9 @@ PyImaging_RawEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { return NULL; } @@ -500,11 +514,11 @@ PyObject * PyImaging_TgaRleEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t ystep = 1; - if (!PyArg_ParseTuple(args, "ss|n", &mode, &rawmode, &ystep)) { + if (!PyArg_ParseTuple(args, "ss|n", &mode_name, &rawmode_name, &ystep)) { return NULL; } @@ -513,6 +527,9 @@ PyImaging_TgaRleEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { return NULL; } @@ -537,7 +554,7 @@ PyImaging_XbmEncoderNew(PyObject *self, PyObject *args) { return NULL; } - if (get_packer(encoder, "1", "1;R") < 0) { + if (get_packer(encoder, IMAGING_MODE_1, IMAGING_RAWMODE_1_R) < 0) { return NULL; } @@ -558,8 +575,8 @@ PyObject * PyImaging_ZipEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t optimize = 0; Py_ssize_t compress_level = -1; Py_ssize_t compress_type = -1; @@ -568,8 +585,8 @@ PyImaging_ZipEncoderNew(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple( args, "ss|nnny#", - &mode, - &rawmode, + &mode_name, + &rawmode_name, &optimize, &compress_level, &compress_type, @@ -598,6 +615,9 @@ PyImaging_ZipEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { free(dictionary); return NULL; @@ -606,7 +626,7 @@ PyImaging_ZipEncoderNew(PyObject *self, PyObject *args) { encoder->encode = ImagingZipEncode; encoder->cleanup = ImagingZipEncodeCleanup; - if (rawmode[0] == 'P') { + if (rawmode == IMAGING_RAWMODE_P || rawmode == IMAGING_RAWMODE_PA) { /* disable filtering */ ((ZIPSTATE *)encoder->state.context)->mode = ZIP_PNG_PALETTE; } @@ -635,8 +655,8 @@ PyObject * PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; char *compname; char *filename; Py_ssize_t fp; @@ -656,7 +676,15 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) { PyObject *item; if (!PyArg_ParseTuple( - args, "sssnsOO", &mode, &rawmode, &compname, &fp, &filename, &tags, &types + args, + "sssnsOO", + &mode_name, + &rawmode_name, + &compname, + &fp, + &filename, + &tags, + &types )) { return NULL; } @@ -694,6 +722,9 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * const rawmode = findRawMode(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { return NULL; } @@ -1071,8 +1102,8 @@ PyObject * PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t quality = 0; Py_ssize_t progressive = 0; Py_ssize_t smooth = 0; @@ -1096,8 +1127,8 @@ PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple( args, "ss|nnnnpnnnnnnOz#y#y#", - &mode, - &rawmode, + &mode_name, + &rawmode_name, &quality, &progressive, &smooth, @@ -1125,11 +1156,14 @@ PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const Mode * const mode = findMode(mode_name); + const RawMode * rawmode = findRawMode(rawmode_name); + // libjpeg-turbo supports different output formats. // We are choosing Pillow's native format (3 color bytes + 1 padding) // to avoid extra conversion in Pack.c. - if (ImagingJpegUseJCSExtensions() && strcmp(rawmode, "RGB") == 0) { - rawmode = "RGBX"; + if (ImagingJpegUseJCSExtensions() && rawmode == IMAGING_RAWMODE_RGB) { + rawmode = IMAGING_RAWMODE_RGBX; } if (get_packer(encoder, mode, rawmode) < 0) { @@ -1187,7 +1221,7 @@ PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) { encoder->encode = ImagingJpegEncode; JPEGENCODERSTATE *jpeg_encoder_state = (JPEGENCODERSTATE *)encoder->state.context; - strncpy(jpeg_encoder_state->rawmode, rawmode, 8); + jpeg_encoder_state->rawmode = rawmode; jpeg_encoder_state->keep_rgb = keep_rgb; jpeg_encoder_state->quality = quality; jpeg_encoder_state->qtables = qarrays; diff --git a/src/libImaging/Jpeg.h b/src/libImaging/Jpeg.h index 7cdba9022..35df91d7f 100644 --- a/src/libImaging/Jpeg.h +++ b/src/libImaging/Jpeg.h @@ -31,9 +31,9 @@ typedef struct { /* Jpeg file mode (empty if not known) */ char jpegmode[8 + 1]; - /* Converter output mode (input to the shuffler). If empty, - convert conversions are disabled */ - char rawmode[8 + 1]; + /* Converter output mode (input to the shuffler) */ + /* If NULL, convert conversions are disabled */ + const RawMode *rawmode; /* If set, trade quality for speed */ int draft; @@ -91,7 +91,7 @@ typedef struct { unsigned int restart_marker_rows; /* Converter input mode (input to the shuffler) */ - char rawmode[8 + 1]; + const RawMode *rawmode; /* Custom quantization tables () */ unsigned int *qtables; diff --git a/src/libImaging/Mode.h b/src/libImaging/Mode.h index 6491beb81..a99103667 100644 --- a/src/libImaging/Mode.h +++ b/src/libImaging/Mode.h @@ -43,6 +43,7 @@ typedef struct { const char * const name; } RawMode; +// Non-rawmode aliases. extern const RawMode * const IMAGING_RAWMODE_1; extern const RawMode * const IMAGING_RAWMODE_CMYK; extern const RawMode * const IMAGING_RAWMODE_F; @@ -60,16 +61,22 @@ extern const RawMode * const IMAGING_RAWMODE_RGBX; extern const RawMode * const IMAGING_RAWMODE_RGBa; extern const RawMode * const IMAGING_RAWMODE_YCbCr; +// BGR modes. extern const RawMode * const IMAGING_RAWMODE_BGR_15; extern const RawMode * const IMAGING_RAWMODE_BGR_16; extern const RawMode * const IMAGING_RAWMODE_BGR_24; extern const RawMode * const IMAGING_RAWMODE_BGR_32; +// I;16 modes. extern const RawMode * const IMAGING_RAWMODE_I_16; extern const RawMode * const IMAGING_RAWMODE_I_16L; extern const RawMode * const IMAGING_RAWMODE_I_16B; extern const RawMode * const IMAGING_RAWMODE_I_16N; +// Rawmodes +extern const RawMode * const IMAGING_RAWMODE_1_R; +extern const RawMode * const IMAGING_RAWMODE_YCC_P; + const RawMode * findRawMode(const char * const name);