use mode structs in encode.c and decode.c

This commit is contained in:
Yay295 2024-04-21 09:54:18 -05:00
parent 7a7e8380cb
commit 97e29dcd2d
4 changed files with 140 additions and 74 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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);