]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/libjpeg/lib/contrib/jcmaster.c
update
[l4.git] / l4 / pkg / libjpeg / lib / contrib / jcmaster.c
index 660883f459a26fa488f109c4568b55db0f8fbd60..caf80a53b38b4d3e8e43d3b0523fd98cc1aa23d1 100644 (file)
@@ -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;
   }
@@ -193,25 +208,11 @@ jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo)
 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;
 }
 
 
@@ -229,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)