summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libjpeg/jcmaster.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/libjpeg/jcmaster.c')
-rw-r--r--src/3rdparty/libjpeg/jcmaster.c198
1 files changed, 107 insertions, 91 deletions
diff --git a/src/3rdparty/libjpeg/jcmaster.c b/src/3rdparty/libjpeg/jcmaster.c
index 5284e58..caf80a5 100644
--- a/src/3rdparty/libjpeg/jcmaster.c
+++ b/src/3rdparty/libjpeg/jcmaster.c
@@ -2,7 +2,7 @@
* jcmaster.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 2003-2010 by Guido Vollbeding.
+ * Modified 2003-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -55,125 +55,140 @@ jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo)
{
#ifdef DCT_SCALING_SUPPORTED
+ /* Sanity check on input image dimensions to prevent overflow in
+ * following calculation.
+ * We do check jpeg_width and jpeg_height in initial_setup below,
+ * but image_width and image_height can come from arbitrary data,
+ * and we need some space for multiplication by block_size.
+ */
+ if (((long) cinfo->image_width >> 24) || ((long) cinfo->image_height >> 24))
+ ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
+
/* Compute actual JPEG image dimensions and DCT scaling choices. */
- if (cinfo->scale_num >= cinfo->scale_denom * 8) {
- /* Provide 8/1 scaling */
- cinfo->jpeg_width = cinfo->image_width << 3;
- cinfo->jpeg_height = cinfo->image_height << 3;
+ if (cinfo->scale_num >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/1 scaling */
+ cinfo->jpeg_width = cinfo->image_width * cinfo->block_size;
+ cinfo->jpeg_height = cinfo->image_height * cinfo->block_size;
cinfo->min_DCT_h_scaled_size = 1;
cinfo->min_DCT_v_scaled_size = 1;
- } else if (cinfo->scale_num >= cinfo->scale_denom * 4) {
- /* Provide 4/1 scaling */
- cinfo->jpeg_width = cinfo->image_width << 2;
- cinfo->jpeg_height = cinfo->image_height << 2;
+ } else if (cinfo->scale_num * 2 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/2 scaling */
+ cinfo->jpeg_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 2L);
+ cinfo->jpeg_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 2L);
cinfo->min_DCT_h_scaled_size = 2;
cinfo->min_DCT_v_scaled_size = 2;
- } else if (cinfo->scale_num * 3 >= cinfo->scale_denom * 8) {
- /* Provide 8/3 scaling */
- cinfo->jpeg_width = (cinfo->image_width << 1) + (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * 2, 3L);
- cinfo->jpeg_height = (cinfo->image_height << 1) + (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * 2, 3L);
+ } else if (cinfo->scale_num * 3 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/3 scaling */
+ cinfo->jpeg_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 3L);
+ cinfo->jpeg_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 3L);
cinfo->min_DCT_h_scaled_size = 3;
cinfo->min_DCT_v_scaled_size = 3;
- } else if (cinfo->scale_num >= cinfo->scale_denom * 2) {
- /* Provide 2/1 scaling */
- cinfo->jpeg_width = cinfo->image_width << 1;
- cinfo->jpeg_height = cinfo->image_height << 1;
+ } else if (cinfo->scale_num * 4 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/4 scaling */
+ cinfo->jpeg_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 4L);
+ cinfo->jpeg_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 4L);
cinfo->min_DCT_h_scaled_size = 4;
cinfo->min_DCT_v_scaled_size = 4;
- } else if (cinfo->scale_num * 5 >= cinfo->scale_denom * 8) {
- /* Provide 8/5 scaling */
- cinfo->jpeg_width = cinfo->image_width + (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * 3, 5L);
- cinfo->jpeg_height = cinfo->image_height + (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * 3, 5L);
+ } else if (cinfo->scale_num * 5 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/5 scaling */
+ cinfo->jpeg_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 5L);
+ cinfo->jpeg_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 5L);
cinfo->min_DCT_h_scaled_size = 5;
cinfo->min_DCT_v_scaled_size = 5;
- } else if (cinfo->scale_num * 3 >= cinfo->scale_denom * 4) {
- /* Provide 4/3 scaling */
- cinfo->jpeg_width = cinfo->image_width + (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width, 3L);
- cinfo->jpeg_height = cinfo->image_height + (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height, 3L);
+ } else if (cinfo->scale_num * 6 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/6 scaling */
+ cinfo->jpeg_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 6L);
+ cinfo->jpeg_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 6L);
cinfo->min_DCT_h_scaled_size = 6;
cinfo->min_DCT_v_scaled_size = 6;
- } else if (cinfo->scale_num * 7 >= cinfo->scale_denom * 8) {
- /* Provide 8/7 scaling */
- cinfo->jpeg_width = cinfo->image_width + (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width, 7L);
- cinfo->jpeg_height = cinfo->image_height + (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height, 7L);
+ } else if (cinfo->scale_num * 7 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/7 scaling */
+ cinfo->jpeg_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 7L);
+ cinfo->jpeg_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 7L);
cinfo->min_DCT_h_scaled_size = 7;
cinfo->min_DCT_v_scaled_size = 7;
- } else if (cinfo->scale_num >= cinfo->scale_denom) {
- /* Provide 1/1 scaling */
- cinfo->jpeg_width = cinfo->image_width;
- cinfo->jpeg_height = cinfo->image_height;
+ } else if (cinfo->scale_num * 8 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/8 scaling */
+ cinfo->jpeg_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 8L);
+ cinfo->jpeg_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 8L);
cinfo->min_DCT_h_scaled_size = 8;
cinfo->min_DCT_v_scaled_size = 8;
- } else if (cinfo->scale_num * 9 >= cinfo->scale_denom * 8) {
- /* Provide 8/9 scaling */
+ } else if (cinfo->scale_num * 9 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/9 scaling */
cinfo->jpeg_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * 8, 9L);
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 9L);
cinfo->jpeg_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * 8, 9L);
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 9L);
cinfo->min_DCT_h_scaled_size = 9;
cinfo->min_DCT_v_scaled_size = 9;
- } else if (cinfo->scale_num * 5 >= cinfo->scale_denom * 4) {
- /* Provide 4/5 scaling */
+ } else if (cinfo->scale_num * 10 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/10 scaling */
cinfo->jpeg_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * 4, 5L);
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 10L);
cinfo->jpeg_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * 4, 5L);
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 10L);
cinfo->min_DCT_h_scaled_size = 10;
cinfo->min_DCT_v_scaled_size = 10;
- } else if (cinfo->scale_num * 11 >= cinfo->scale_denom * 8) {
- /* Provide 8/11 scaling */
+ } else if (cinfo->scale_num * 11 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/11 scaling */
cinfo->jpeg_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * 8, 11L);
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 11L);
cinfo->jpeg_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * 8, 11L);
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 11L);
cinfo->min_DCT_h_scaled_size = 11;
cinfo->min_DCT_v_scaled_size = 11;
- } else if (cinfo->scale_num * 3 >= cinfo->scale_denom * 2) {
- /* Provide 2/3 scaling */
+ } else if (cinfo->scale_num * 12 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/12 scaling */
cinfo->jpeg_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * 2, 3L);
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 12L);
cinfo->jpeg_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * 2, 3L);
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 12L);
cinfo->min_DCT_h_scaled_size = 12;
cinfo->min_DCT_v_scaled_size = 12;
- } else if (cinfo->scale_num * 13 >= cinfo->scale_denom * 8) {
- /* Provide 8/13 scaling */
+ } else if (cinfo->scale_num * 13 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/13 scaling */
cinfo->jpeg_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * 8, 13L);
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 13L);
cinfo->jpeg_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * 8, 13L);
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 13L);
cinfo->min_DCT_h_scaled_size = 13;
cinfo->min_DCT_v_scaled_size = 13;
- } else if (cinfo->scale_num * 7 >= cinfo->scale_denom * 4) {
- /* Provide 4/7 scaling */
+ } else if (cinfo->scale_num * 14 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/14 scaling */
cinfo->jpeg_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * 4, 7L);
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 14L);
cinfo->jpeg_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * 4, 7L);
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 14L);
cinfo->min_DCT_h_scaled_size = 14;
cinfo->min_DCT_v_scaled_size = 14;
- } else if (cinfo->scale_num * 15 >= cinfo->scale_denom * 8) {
- /* Provide 8/15 scaling */
+ } else if (cinfo->scale_num * 15 >= cinfo->scale_denom * cinfo->block_size) {
+ /* Provide block_size/15 scaling */
cinfo->jpeg_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * 8, 15L);
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 15L);
cinfo->jpeg_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * 8, 15L);
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 15L);
cinfo->min_DCT_h_scaled_size = 15;
cinfo->min_DCT_v_scaled_size = 15;
} else {
- /* Provide 1/2 scaling */
+ /* Provide block_size/16 scaling */
cinfo->jpeg_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width, 2L);
+ jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 16L);
cinfo->jpeg_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height, 2L);
+ jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 16L);
cinfo->min_DCT_h_scaled_size = 16;
cinfo->min_DCT_v_scaled_size = 16;
}
@@ -187,35 +202,17 @@ jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo)
cinfo->min_DCT_v_scaled_size = DCTSIZE;
#endif /* DCT_SCALING_SUPPORTED */
-
- cinfo->block_size = DCTSIZE;
- cinfo->natural_order = jpeg_natural_order;
- cinfo->lim_Se = DCTSIZE2-1;
}
LOCAL(void)
jpeg_calc_trans_dimensions (j_compress_ptr cinfo)
{
- if (cinfo->min_DCT_h_scaled_size < 1 || cinfo->min_DCT_h_scaled_size > 16
- || cinfo->min_DCT_h_scaled_size != cinfo->min_DCT_v_scaled_size)
+ if (cinfo->min_DCT_h_scaled_size != cinfo->min_DCT_v_scaled_size)
ERREXIT2(cinfo, JERR_BAD_DCTSIZE,
cinfo->min_DCT_h_scaled_size, cinfo->min_DCT_v_scaled_size);
cinfo->block_size = cinfo->min_DCT_h_scaled_size;
-
- switch (cinfo->block_size) {
- case 2: cinfo->natural_order = jpeg_natural_order2; break;
- case 3: cinfo->natural_order = jpeg_natural_order3; break;
- case 4: cinfo->natural_order = jpeg_natural_order4; break;
- case 5: cinfo->natural_order = jpeg_natural_order5; break;
- case 6: cinfo->natural_order = jpeg_natural_order6; break;
- case 7: cinfo->natural_order = jpeg_natural_order7; break;
- default: cinfo->natural_order = jpeg_natural_order; break;
- }
-
- cinfo->lim_Se = cinfo->block_size < DCTSIZE ?
- cinfo->block_size * cinfo->block_size - 1 : DCTSIZE2-1;
}
@@ -233,6 +230,25 @@ initial_setup (j_compress_ptr cinfo, boolean transcode_only)
else
jpeg_calc_jpeg_dimensions(cinfo);
+ /* Sanity check on block_size */
+ if (cinfo->block_size < 1 || cinfo->block_size > 16)
+ ERREXIT2(cinfo, JERR_BAD_DCTSIZE, cinfo->block_size, cinfo->block_size);
+
+ /* Derive natural_order from block_size */
+ switch (cinfo->block_size) {
+ case 2: cinfo->natural_order = jpeg_natural_order2; break;
+ case 3: cinfo->natural_order = jpeg_natural_order3; break;
+ case 4: cinfo->natural_order = jpeg_natural_order4; break;
+ case 5: cinfo->natural_order = jpeg_natural_order5; break;
+ case 6: cinfo->natural_order = jpeg_natural_order6; break;
+ case 7: cinfo->natural_order = jpeg_natural_order7; break;
+ default: cinfo->natural_order = jpeg_natural_order; break;
+ }
+
+ /* Derive lim_Se from block_size */
+ cinfo->lim_Se = cinfo->block_size < DCTSIZE ?
+ cinfo->block_size * cinfo->block_size - 1 : DCTSIZE2-1;
+
/* Sanity check on image dimensions */
if (cinfo->jpeg_height <= 0 || cinfo->jpeg_width <= 0 ||
cinfo->num_components <= 0 || cinfo->input_components <= 0)