diff options
| author | shumkovnd <[email protected]> | 2023-11-10 14:39:34 +0300 | 
|---|---|---|
| committer | shumkovnd <[email protected]> | 2023-11-10 16:42:24 +0300 | 
| commit | 77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch) | |
| tree | c51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/Pillow/py3/libImaging/JpegEncode.c | |
| parent | dd6d20cadb65582270ac23f4b3b14ae189704b9d (diff) | |
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/python/Pillow/py3/libImaging/JpegEncode.c')
| -rw-r--r-- | contrib/python/Pillow/py3/libImaging/JpegEncode.c | 354 | 
1 files changed, 354 insertions, 0 deletions
diff --git a/contrib/python/Pillow/py3/libImaging/JpegEncode.c b/contrib/python/Pillow/py3/libImaging/JpegEncode.c new file mode 100644 index 00000000000..2a24eff39ca --- /dev/null +++ b/contrib/python/Pillow/py3/libImaging/JpegEncode.c @@ -0,0 +1,354 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * coder for JPEG data + * + * history: + * 1996-05-06 fl   created + * 1996-07-16 fl   don't drop last block of encoded data + * 1996-12-30 fl   added quality and progressive settings + * 1997-01-08 fl   added streamtype settings + * 1998-01-31 fl   adapted to libjpeg 6a + * 1998-07-12 fl   added YCbCr support + * 2001-04-16 fl   added DPI write support + * + * Copyright (c) 1997-2001 by Secret Labs AB + * Copyright (c) 1995-1997 by Fredrik Lundh + * + * See the README file for details on usage and redistribution. + */ + +#include "Imaging.h" + +#ifdef HAVE_LIBJPEG + +#undef HAVE_PROTOTYPES +#undef HAVE_STDLIB_H +#undef HAVE_STDDEF_H +#undef UINT8 +#undef UINT16 +#undef UINT32 +#undef INT16 +#undef INT32 + +#include "Jpeg.h" + +/* -------------------------------------------------------------------- */ +/* Suspending output handler                                            */ +/* -------------------------------------------------------------------- */ + +METHODDEF(void) +stub(j_compress_ptr cinfo) { /* empty */ } + +METHODDEF(boolean) +empty_output_buffer(j_compress_ptr cinfo) { +    /* Suspension */ +    return FALSE; +} + +GLOBAL(void) +jpeg_buffer_dest(j_compress_ptr cinfo, JPEGDESTINATION *destination) { +    cinfo->dest = (void *)destination; + +    destination->pub.init_destination = stub; +    destination->pub.empty_output_buffer = empty_output_buffer; +    destination->pub.term_destination = stub; +} + +/* -------------------------------------------------------------------- */ +/* Error handler                                                        */ +/* -------------------------------------------------------------------- */ + +METHODDEF(void) +error(j_common_ptr cinfo) { +    JPEGERROR *error; +    error = (JPEGERROR *)cinfo->err; +    (*cinfo->err->output_message)(cinfo); +    longjmp(error->setjmp_buffer, 1); +} + +/* -------------------------------------------------------------------- */ +/* Encoder                                                              */ +/* -------------------------------------------------------------------- */ + +int +ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) { +    JPEGENCODERSTATE *context = (JPEGENCODERSTATE *)state->context; +    int ok; + +    if (setjmp(context->error.setjmp_buffer)) { +        /* JPEG error handler */ +        jpeg_destroy_compress(&context->cinfo); +        state->errcode = IMAGING_CODEC_BROKEN; +        return -1; +    } + +    if (!state->state) { +        /* Setup compression context (very similar to the decoder) */ +        context->cinfo.err = jpeg_std_error(&context->error.pub); +        context->error.pub.error_exit = error; +        jpeg_create_compress(&context->cinfo); +        jpeg_buffer_dest(&context->cinfo, &context->destination); + +        context->extra_offset = 0; + +        /* Ready to encode */ +        state->state = 1; +    } + +    /* Load the destination buffer */ +    context->destination.pub.next_output_byte = buf; +    context->destination.pub.free_in_buffer = bytes; + +    switch (state->state) { +        case 1: + +            context->cinfo.image_width = state->xsize; +            context->cinfo.image_height = state->ysize; + +            switch (state->bits) { +                case 8: +                    context->cinfo.input_components = 1; +                    context->cinfo.in_color_space = JCS_GRAYSCALE; +                    break; +                case 24: +                    context->cinfo.input_components = 3; +                    if (strcmp(im->mode, "YCbCr") == 0) { +                        context->cinfo.in_color_space = JCS_YCbCr; +                    } else { +                        context->cinfo.in_color_space = JCS_RGB; +                    } +                    break; +                case 32: +                    context->cinfo.input_components = 4; +                    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; +                default: +                    state->errcode = IMAGING_CODEC_CONFIG; +                    return -1; +            } + +            /* Compressor configuration */ +            jpeg_set_defaults(&context->cinfo); + +            /* Use custom quantization tables */ +            if (context->qtables) { +                int i; +                int quality = 100; +                int last_q = 0; +                if (context->quality != -1) { +                    quality = context->quality; +                } +                for (i = 0; i < context->qtablesLen; i++) { +                    jpeg_add_quant_table( +                        &context->cinfo, +                        i, +                        &context->qtables[i * DCTSIZE2], +                        quality, +                        FALSE); +                    context->cinfo.comp_info[i].quant_tbl_no = i; +                    last_q = i; +                } +                if (context->qtablesLen == 1) { +                    // jpeg_set_defaults created two qtables internally, but we only +                    // wanted one. +                    jpeg_add_quant_table( +                        &context->cinfo, 1, &context->qtables[0], quality, FALSE); +                } +                for (i = last_q; i < context->cinfo.num_components; i++) { +                    context->cinfo.comp_info[i].quant_tbl_no = last_q; +                } +            } else if (context->quality != -1) { +                jpeg_set_quality(&context->cinfo, context->quality, TRUE); +            } + +            /* Set subsampling options */ +            switch (context->subsampling) { +                case 0: /* 1x1 1x1 1x1 (4:4:4) : None */ +                { +                    context->cinfo.comp_info[0].h_samp_factor = 1; +                    context->cinfo.comp_info[0].v_samp_factor = 1; +                    context->cinfo.comp_info[1].h_samp_factor = 1; +                    context->cinfo.comp_info[1].v_samp_factor = 1; +                    context->cinfo.comp_info[2].h_samp_factor = 1; +                    context->cinfo.comp_info[2].v_samp_factor = 1; +                    break; +                } +                case 1: /* 2x1, 1x1, 1x1 (4:2:2) : Medium */ +                { +                    context->cinfo.comp_info[0].h_samp_factor = 2; +                    context->cinfo.comp_info[0].v_samp_factor = 1; +                    context->cinfo.comp_info[1].h_samp_factor = 1; +                    context->cinfo.comp_info[1].v_samp_factor = 1; +                    context->cinfo.comp_info[2].h_samp_factor = 1; +                    context->cinfo.comp_info[2].v_samp_factor = 1; +                    break; +                } +                case 2: /* 2x2, 1x1, 1x1 (4:2:0) : High */ +                { +                    context->cinfo.comp_info[0].h_samp_factor = 2; +                    context->cinfo.comp_info[0].v_samp_factor = 2; +                    context->cinfo.comp_info[1].h_samp_factor = 1; +                    context->cinfo.comp_info[1].v_samp_factor = 1; +                    context->cinfo.comp_info[2].h_samp_factor = 1; +                    context->cinfo.comp_info[2].v_samp_factor = 1; +                    break; +                } +                default: { +                    /* Use the lib's default */ +                    break; +                } +            } +            if (context->progressive) { +                jpeg_simple_progression(&context->cinfo); +            } +            context->cinfo.smoothing_factor = context->smooth; +            context->cinfo.optimize_coding = (boolean)context->optimize; +            if (context->xdpi > 0 && context->ydpi > 0) { +                context->cinfo.write_JFIF_header = TRUE; +                context->cinfo.density_unit = 1; /* dots per inch */ +                context->cinfo.X_density = context->xdpi; +                context->cinfo.Y_density = context->ydpi; +            } +            switch (context->streamtype) { +                case 1: +                    /* tables only -- not yet implemented */ +                    state->errcode = IMAGING_CODEC_CONFIG; +                    return -1; +                case 2: +                    /* image only */ +                    jpeg_suppress_tables(&context->cinfo, TRUE); +                    jpeg_start_compress(&context->cinfo, FALSE); +                    /* suppress extra section */ +                    context->extra_offset = context->extra_size; +                    break; +                default: +                    /* interchange stream */ +                    jpeg_start_compress(&context->cinfo, TRUE); +                    break; +            } +            state->state++; +            /* fall through */ + +        case 2: +            // check for exif len + 'APP1' header bytes +            if (context->rawExifLen + 5 > context->destination.pub.free_in_buffer) { +                break; +            } +            // add exif header +            if (context->rawExifLen > 0) { +                jpeg_write_marker( +                    &context->cinfo, +                    JPEG_APP0 + 1, +                    (unsigned char *)context->rawExif, +                    context->rawExifLen); +            } + +            state->state++; +            /* fall through */ +        case 3: + +            if (context->extra) { +                /* copy extra buffer to output buffer */ +                unsigned int n = context->extra_size - context->extra_offset; +                if (n > context->destination.pub.free_in_buffer) { +                    n = context->destination.pub.free_in_buffer; +                } +                memcpy( +                    context->destination.pub.next_output_byte, +                    context->extra + context->extra_offset, +                    n); +                context->destination.pub.next_output_byte += n; +                context->destination.pub.free_in_buffer -= n; +                context->extra_offset += n; +                if (context->extra_offset >= context->extra_size) { +                    state->state++; +                } else { +                    break; +                } +            } else { +                state->state++; +            } + +        case 4: + +            if (context->comment) { +                jpeg_write_marker(&context->cinfo, JPEG_COM, (unsigned char *)context->comment, context->comment_size); +            } +            state->state++; + +        case 5: +            if (1024 > context->destination.pub.free_in_buffer) { +                break; +            } + +            ok = 1; +            while (state->y < state->ysize) { +                state->shuffle( +                    state->buffer, +                    (UINT8 *)im->image[state->y + state->yoff] + +                        state->xoff * im->pixelsize, +                    state->xsize); +                ok = jpeg_write_scanlines(&context->cinfo, &state->buffer, 1); +                if (ok != 1) { +                    break; +                } +                state->y++; +            } + +            if (ok != 1) { +                break; +            } +            state->state++; +            /* fall through */ + +        case 6: + +            /* Finish compression */ +            if (context->destination.pub.free_in_buffer < 100) { +                break; +            } +            jpeg_finish_compress(&context->cinfo); + +            /* Clean up */ +            if (context->comment) { +                free(context->comment); +                context->comment = NULL; +            } +            if (context->extra) { +                free(context->extra); +                context->extra = NULL; +            } +            if (context->rawExif) { +                free(context->rawExif); +                context->rawExif = NULL; +            } +            if (context->qtables) { +                free(context->qtables); +                context->qtables = NULL; +            } + +            jpeg_destroy_compress(&context->cinfo); +            /* if (jerr.pub.num_warnings) return BROKEN; */ +            state->errcode = IMAGING_CODEC_END; +            break; +    } + +    /* Return number of bytes in output buffer */ +    return context->destination.pub.next_output_byte - buf; +} + +const char * +ImagingJpegVersion(void) { +    static char version[20]; +    sprintf(version, "%d.%d", JPEG_LIB_VERSION / 10, JPEG_LIB_VERSION % 10); +    return version; +} + +#endif  | 
