Pillow

Форк
0
/
JpegDecode.c 
304 строки · 9.6 Кб
1
/*
2
 * The Python Imaging Library.
3
 * $Id$
4
 *
5
 * decoder for JPEG image data.
6
 *
7
 * history:
8
 * 1996-05-02 fl   Created
9
 * 1996-05-05 fl   Handle small JPEG files correctly
10
 * 1996-05-28 fl   Added "draft mode" support
11
 * 1997-01-25 fl   Added colour conversion override
12
 * 1998-01-31 fl   Adapted to libjpeg 6a
13
 * 1998-07-12 fl   Extended YCbCr support
14
 * 1998-12-29 fl   Added new state to handle suspension in multipass modes
15
 * 2000-10-12 fl   Suppress warnings
16
 * 2000-12-04 fl   Suppress errors beyond end of image data
17
 *
18
 * Copyright (c) 1998-2000 Secret Labs AB
19
 * Copyright (c) 1996-2000 Fredrik Lundh
20
 *
21
 * See the README file for details on usage and redistribution.
22
 */
23

24
#include "Imaging.h"
25

26
#ifdef HAVE_LIBJPEG
27

28
#undef HAVE_PROTOTYPES
29
#undef HAVE_STDLIB_H
30
#undef HAVE_STDDEF_H
31
#undef UINT8
32
#undef UINT16
33
#undef UINT32
34
#undef INT16
35
#undef INT32
36

37
#include "Jpeg.h"
38

39
#define STRINGIFY(x) #x
40
#define TOSTRING(x) STRINGIFY(x)
41

42
// There is no way to compare versions on compile time,
43
// so we have to do that in runtime.
44
#ifdef LIBJPEG_TURBO_VERSION
45
char *libjpeg_turbo_version = TOSTRING(LIBJPEG_TURBO_VERSION);
46
#else
47
char *libjpeg_turbo_version = NULL;
48
#endif
49

50
int
51
ImagingJpegUseJCSExtensions() {
52
    int use_jcs_extensions = 0;
53
#ifdef JCS_EXTENSIONS
54
#if defined(LIBJPEG_TURBO_VERSION_NUMBER)
55
#if LIBJPEG_TURBO_VERSION_NUMBER >= 1002010
56
    use_jcs_extensions = 1;
57
#endif
58
#else
59
    if (libjpeg_turbo_version) {
60
        use_jcs_extensions = strcmp(libjpeg_turbo_version, "1.2.1") >= 0;
61
    }
62
#endif
63
#endif
64
    return use_jcs_extensions;
65
}
66

67
/* -------------------------------------------------------------------- */
68
/* Suspending input handler                                             */
69
/* -------------------------------------------------------------------- */
70

71
METHODDEF(void)
72
stub(j_decompress_ptr cinfo) { /* empty */ }
73

74
METHODDEF(boolean)
75
fill_input_buffer(j_decompress_ptr cinfo) {
76
    /* Suspension */
77
    return FALSE;
78
}
79

80
METHODDEF(void)
81
skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
82
    JPEGSOURCE *source = (JPEGSOURCE *)cinfo->src;
83

84
    if (num_bytes > (long)source->pub.bytes_in_buffer) {
85
        /* We need to skip more data than we have in the buffer.
86
           This will force the JPEG library to suspend decoding. */
87
        source->skip = num_bytes - source->pub.bytes_in_buffer;
88
        source->pub.next_input_byte += source->pub.bytes_in_buffer;
89
        source->pub.bytes_in_buffer = 0;
90
    } else {
91
        /* Skip portion of the buffer */
92
        source->pub.bytes_in_buffer -= num_bytes;
93
        source->pub.next_input_byte += num_bytes;
94
        source->skip = 0;
95
    }
96
}
97

98
GLOBAL(void)
99
jpeg_buffer_src(j_decompress_ptr cinfo, JPEGSOURCE *source) {
100
    cinfo->src = (void *)source;
101

102
    /* Prepare for suspending reader */
103
    source->pub.init_source = stub;
104
    source->pub.fill_input_buffer = fill_input_buffer;
105
    source->pub.skip_input_data = skip_input_data;
106
    source->pub.resync_to_restart = jpeg_resync_to_restart;
107
    source->pub.term_source = stub;
108
    source->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
109

110
    source->skip = 0;
111
}
112

113
/* -------------------------------------------------------------------- */
114
/* Error handler                                                        */
115
/* -------------------------------------------------------------------- */
116

117
METHODDEF(void)
118
error(j_common_ptr cinfo) {
119
    JPEGERROR *error;
120
    error = (JPEGERROR *)cinfo->err;
121
    longjmp(error->setjmp_buffer, 1);
122
}
123

124
METHODDEF(void)
125
output(j_common_ptr cinfo) { /* nothing */ }
126

127
/* -------------------------------------------------------------------- */
128
/* Decoder                                                              */
129
/* -------------------------------------------------------------------- */
130

131
int
132
ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
133
    JPEGSTATE *context = (JPEGSTATE *)state->context;
134
    int ok;
135

136
    if (setjmp(context->error.setjmp_buffer)) {
137
        /* JPEG error handler */
138
        jpeg_destroy_decompress(&context->cinfo);
139
        state->errcode = IMAGING_CODEC_BROKEN;
140
        return -1;
141
    }
142

143
    if (!state->state) {
144
        /* Setup decompression context */
145
        context->cinfo.err = jpeg_std_error(&context->error.pub);
146
        context->error.pub.error_exit = error;
147
        context->error.pub.output_message = output;
148
        jpeg_create_decompress(&context->cinfo);
149
        jpeg_buffer_src(&context->cinfo, &context->source);
150

151
        /* Ready to decode */
152
        state->state = 1;
153
    }
154

155
    /* Load the source buffer */
156
    context->source.pub.next_input_byte = buf;
157
    context->source.pub.bytes_in_buffer = bytes;
158

159
    if (context->source.skip > 0) {
160
        skip_input_data(&context->cinfo, context->source.skip);
161
        if (context->source.skip > 0) {
162
            return context->source.pub.next_input_byte - buf;
163
        }
164
    }
165

166
    switch (state->state) {
167
        case 1:
168

169
            /* Read JPEG header, until we find an image body. */
170
            do {
171
                /* Note that we cannot return unless we have decoded
172
                   as much data as possible. */
173
                ok = jpeg_read_header(&context->cinfo, FALSE);
174

175
            } while (ok == JPEG_HEADER_TABLES_ONLY);
176

177
            if (ok == JPEG_SUSPENDED) {
178
                break;
179
            }
180

181
            /* Decoder settings */
182

183
            /* jpegmode indicates what's in the file; if not set, we'll
184
               trust the decoder */
185
            if (strcmp(context->jpegmode, "L") == 0) {
186
                context->cinfo.jpeg_color_space = JCS_GRAYSCALE;
187
            } else if (strcmp(context->jpegmode, "RGB") == 0) {
188
                context->cinfo.jpeg_color_space = JCS_RGB;
189
            } else if (strcmp(context->jpegmode, "CMYK") == 0) {
190
                context->cinfo.jpeg_color_space = JCS_CMYK;
191
            } else if (strcmp(context->jpegmode, "YCbCr") == 0) {
192
                context->cinfo.jpeg_color_space = JCS_YCbCr;
193
            } else if (strcmp(context->jpegmode, "YCbCrK") == 0) {
194
                context->cinfo.jpeg_color_space = JCS_YCCK;
195
            }
196

197
            /* rawmode indicates what we want from the decoder.  if not
198
               set, conversions are disabled */
199
            if (strcmp(context->rawmode, "L") == 0) {
200
                context->cinfo.out_color_space = JCS_GRAYSCALE;
201
            } else if (strcmp(context->rawmode, "RGB") == 0) {
202
                context->cinfo.out_color_space = JCS_RGB;
203
            }
204
#ifdef JCS_EXTENSIONS
205
            else if (strcmp(context->rawmode, "RGBX") == 0) {
206
                context->cinfo.out_color_space = JCS_EXT_RGBX;
207
            }
208
#endif
209
            else if (strcmp(context->rawmode, "CMYK") == 0 ||
210
                     strcmp(context->rawmode, "CMYK;I") == 0) {
211
                context->cinfo.out_color_space = JCS_CMYK;
212
            } else if (strcmp(context->rawmode, "YCbCr") == 0) {
213
                context->cinfo.out_color_space = JCS_YCbCr;
214
            } else if (strcmp(context->rawmode, "YCbCrK") == 0) {
215
                context->cinfo.out_color_space = JCS_YCCK;
216
            } else {
217
                /* Disable decoder conversions */
218
                context->cinfo.jpeg_color_space = JCS_UNKNOWN;
219
                context->cinfo.out_color_space = JCS_UNKNOWN;
220
            }
221

222
            if (context->scale > 1) {
223
                context->cinfo.scale_num = 1;
224
                context->cinfo.scale_denom = context->scale;
225
            }
226
            if (context->draft) {
227
                context->cinfo.do_fancy_upsampling = FALSE;
228
                context->cinfo.dct_method = JDCT_FASTEST;
229
            }
230

231
            state->state++;
232
            /* fall through */
233

234
        case 2:
235

236
            /* Set things up for decompression (this processes the entire
237
               file if necessary to return data line by line) */
238
            if (!jpeg_start_decompress(&context->cinfo)) {
239
                break;
240
            }
241

242
            state->state++;
243
            /* fall through */
244

245
        case 3:
246

247
            /* Decompress a single line of data */
248
            ok = 1;
249
            while (state->y < state->ysize) {
250
                ok = jpeg_read_scanlines(&context->cinfo, &state->buffer, 1);
251
                if (ok != 1) {
252
                    break;
253
                }
254
                state->shuffle(
255
                    (UINT8 *)im->image[state->y + state->yoff] +
256
                        state->xoff * im->pixelsize,
257
                    state->buffer,
258
                    state->xsize
259
                );
260
                state->y++;
261
            }
262
            if (ok != 1) {
263
                break;
264
            }
265
            state->state++;
266
            /* fall through */
267

268
        case 4:
269

270
            /* Finish decompression */
271
            if (!jpeg_finish_decompress(&context->cinfo)) {
272
                /* FIXME: add strictness mode test */
273
                if (state->y < state->ysize) {
274
                    break;
275
                }
276
            }
277

278
            /* Clean up */
279
            jpeg_destroy_decompress(&context->cinfo);
280
            /* if (jerr.pub.num_warnings) return BROKEN; */
281
            return -1;
282
    }
283

284
    /* Return number of bytes consumed */
285
    return context->source.pub.next_input_byte - buf;
286
}
287

288
/* -------------------------------------------------------------------- */
289
/* Cleanup                                                              */
290
/* -------------------------------------------------------------------- */
291

292
int
293
ImagingJpegDecodeCleanup(ImagingCodecState state) {
294
    /* called to free the decompression engine when the decode terminates
295
       due to a corrupt or truncated image
296
    */
297
    JPEGSTATE *context = (JPEGSTATE *)state->context;
298

299
    /* Clean up */
300
    jpeg_destroy_decompress(&context->cinfo);
301
    return -1;
302
}
303

304
#endif
305

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.