mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 01:46:18 +03:00
Merge pull request #1989 from uploadcare/jpeg-loading-without-convertion
Use RGBX rawmode for RGB JPEG images
This commit is contained in:
commit
9797e7bbfa
8
decode.c
8
decode.c
|
@ -819,6 +819,7 @@ PyImaging_JpegDecoderNew(PyObject* self, PyObject* args)
|
||||||
char* jpegmode; /* what's in the file */
|
char* jpegmode; /* what's in the file */
|
||||||
int scale = 1;
|
int scale = 1;
|
||||||
int draft = 0;
|
int draft = 0;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ssz|ii", &mode, &rawmode, &jpegmode,
|
if (!PyArg_ParseTuple(args, "ssz|ii", &mode, &rawmode, &jpegmode,
|
||||||
&scale, &draft))
|
&scale, &draft))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -830,6 +831,13 @@ PyImaging_JpegDecoderNew(PyObject* self, PyObject* args)
|
||||||
if (decoder == NULL)
|
if (decoder == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// 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 (get_unpacker(decoder, mode, rawmode) < 0)
|
if (get_unpacker(decoder, mode, rawmode) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
9
encode.c
9
encode.c
|
@ -691,6 +691,13 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
||||||
if (encoder == NULL)
|
if (encoder == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// 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 (get_packer(encoder, mode, rawmode) < 0)
|
if (get_packer(encoder, mode, rawmode) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -719,6 +726,8 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
||||||
|
|
||||||
encoder->encode = ImagingJpegEncode;
|
encoder->encode = ImagingJpegEncode;
|
||||||
|
|
||||||
|
strncpy(((JPEGENCODERSTATE*)encoder->state.context)->rawmode, rawmode, 8);
|
||||||
|
|
||||||
((JPEGENCODERSTATE*)encoder->state.context)->quality = quality;
|
((JPEGENCODERSTATE*)encoder->state.context)->quality = quality;
|
||||||
((JPEGENCODERSTATE*)encoder->state.context)->qtables = qarrays;
|
((JPEGENCODERSTATE*)encoder->state.context)->qtables = qarrays;
|
||||||
((JPEGENCODERSTATE*)encoder->state.context)->qtablesLen = qtablesLen;
|
((JPEGENCODERSTATE*)encoder->state.context)->qtablesLen = qtablesLen;
|
||||||
|
|
|
@ -407,6 +407,7 @@ extern int ImagingHexDecode(Imaging im, ImagingCodecState state,
|
||||||
extern int ImagingJpegDecode(Imaging im, ImagingCodecState state,
|
extern int ImagingJpegDecode(Imaging im, ImagingCodecState state,
|
||||||
UINT8* buffer, int bytes);
|
UINT8* buffer, int bytes);
|
||||||
extern int ImagingJpegDecodeCleanup(ImagingCodecState state);
|
extern int ImagingJpegDecodeCleanup(ImagingCodecState state);
|
||||||
|
extern int ImagingJpegUseJCSExtensions(void);
|
||||||
|
|
||||||
extern int ImagingJpegEncode(Imaging im, ImagingCodecState state,
|
extern int ImagingJpegEncode(Imaging im, ImagingCodecState state,
|
||||||
UINT8* buffer, int bytes);
|
UINT8* buffer, int bytes);
|
||||||
|
|
|
@ -88,6 +88,9 @@ typedef struct {
|
||||||
/* Chroma Subsampling (-1=default, 0=none, 1=medium, 2=high) */
|
/* Chroma Subsampling (-1=default, 0=none, 1=medium, 2=high) */
|
||||||
int subsampling;
|
int subsampling;
|
||||||
|
|
||||||
|
/* Converter input mode (input to the shuffler) */
|
||||||
|
char rawmode[8+1];
|
||||||
|
|
||||||
/* Custom quantization tables () */
|
/* Custom quantization tables () */
|
||||||
unsigned int *qtables;
|
unsigned int *qtables;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,35 @@
|
||||||
#include "Jpeg.h"
|
#include "Jpeg.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define STRINGIFY(x) #x
|
||||||
|
#define TOSTRING(x) STRINGIFY(x)
|
||||||
|
|
||||||
|
// There is no way to compare versions on compile time,
|
||||||
|
// so we have to do that in runtime.
|
||||||
|
#ifdef LIBJPEG_TURBO_VERSION
|
||||||
|
char *libjpeg_turbo_version = TOSTRING(LIBJPEG_TURBO_VERSION);
|
||||||
|
#else
|
||||||
|
char *libjpeg_turbo_version = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
ImagingJpegUseJCSExtensions()
|
||||||
|
{
|
||||||
|
int use_jcs_extensions = 0;
|
||||||
|
#ifdef JCS_EXTENSIONS
|
||||||
|
#if defined(LIBJPEG_TURBO_VERSION_NUMBER)
|
||||||
|
#if LIBJPEG_TURBO_VERSION_NUMBER >= 1002010
|
||||||
|
use_jcs_extensions = 1;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
if (libjpeg_turbo_version) {
|
||||||
|
use_jcs_extensions = strcmp(libjpeg_turbo_version, "1.2.1") >= 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return use_jcs_extensions;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Suspending input handler */
|
/* Suspending input handler */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -189,6 +218,10 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
context->cinfo.out_color_space = JCS_GRAYSCALE;
|
context->cinfo.out_color_space = JCS_GRAYSCALE;
|
||||||
else if (strcmp(context->rawmode, "RGB") == 0)
|
else if (strcmp(context->rawmode, "RGB") == 0)
|
||||||
context->cinfo.out_color_space = JCS_RGB;
|
context->cinfo.out_color_space = JCS_RGB;
|
||||||
|
#ifdef JCS_EXTENSIONS
|
||||||
|
else if (strcmp(context->rawmode, "RGBX") == 0)
|
||||||
|
context->cinfo.out_color_space = JCS_EXT_RGBX;
|
||||||
|
#endif
|
||||||
else if (strcmp(context->rawmode, "CMYK") == 0 ||
|
else if (strcmp(context->rawmode, "CMYK") == 0 ||
|
||||||
strcmp(context->rawmode, "CMYK;I") == 0)
|
strcmp(context->rawmode, "CMYK;I") == 0)
|
||||||
context->cinfo.out_color_space = JCS_CMYK;
|
context->cinfo.out_color_space = JCS_CMYK;
|
||||||
|
|
|
@ -135,6 +135,10 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
case 32:
|
case 32:
|
||||||
context->cinfo.input_components = 4;
|
context->cinfo.input_components = 4;
|
||||||
context->cinfo.in_color_space = JCS_CMYK;
|
context->cinfo.in_color_space = JCS_CMYK;
|
||||||
|
#ifdef JCS_EXTENSIONS
|
||||||
|
if (strcmp(context->rawmode, "RGBX") == 0)
|
||||||
|
context->cinfo.in_color_space = JCS_EXT_RGBX;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
state->errcode = IMAGING_CODEC_CONFIG;
|
state->errcode = IMAGING_CODEC_CONFIG;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user