]> granicus.if.org Git - libjpeg-turbo/commitdiff
The Independent JPEG Group's JPEG software v8a jpeg-8a
authorGuido Vollbeding <jpeg-info@uc.ag>
Sun, 28 Feb 2010 00:00:00 +0000 (00:00 +0000)
committerDRC <information@libjpeg-turbo.org>
Mon, 27 Jul 2015 18:46:36 +0000 (13:46 -0500)
README
change.log
configure
configure.ac
jcapimin.c
jcmaster.c
jddctmgr.c
jidctflt.c
jpegtran.c
jversion.h
rdbmp.c

diff --git a/README b/README
index 7bc588f03847c26507e22582de1a674c039e7a3b..da0c488f6dce1b12a9a62db8ac7ac5fc486598ed 100644 (file)
--- a/README
+++ b/README
@@ -1,8 +1,8 @@
 The Independent JPEG Group's JPEG software
 ==========================================
 
-README for release 8 of 10-Jan-2010
-===================================
+README for release 8a of 28-Feb-2010
+====================================
 
 This distribution contains the eighth public release of the Independent JPEG
 Group's free JPEG software.  You are welcome to redistribute this software and
@@ -254,8 +254,8 @@ ARCHIVE LOCATIONS
 The "official" archive site for this software is www.ijg.org.
 The most recent released version can always be found there in
 directory "files".  This particular version will be archived as
-http://www.ijg.org/files/jpegsrc.v8.tar.gz, and in Windows-compatible
-"zip" archive format as http://www.ijg.org/files/jpegsr8.zip.
+http://www.ijg.org/files/jpegsrc.v8a.tar.gz, and in Windows-compatible
+"zip" archive format as http://www.ijg.org/files/jpegsr8a.zip.
 
 The JPEG FAQ (Frequently Asked Questions) article is a source of some
 general information about JPEG.
@@ -318,7 +318,7 @@ image files indefinitely.)
 TO DO
 =====
 
-Version 8.0 is the first release of a new generation JPEG standard
+Version 8 is the first release of a new generation JPEG standard
 to overcome the limitations of the original JPEG specification.
 More features are being prepared for coming releases...
 
index 58ea3eb3bed56a7a1a2f5b7dde87dcb8dfb018cf..56d096f9dd6df000027b122a34329c84987e9b96 100644 (file)
@@ -1,6 +1,18 @@
 CHANGE LOG for Independent JPEG Group's JPEG software
 
 
+Version 8a  28-Feb-2010
+-----------------------
+
+Writing tables-only datastreams via jpeg_write_tables works again.
+
+Support 32-bit BMPs (RGB image with Alpha channel) for read in cjpeg.
+Thank to Brett Blackham for the suggestion.
+
+Improve accuracy in floating point IDCT calculation.
+Thank to Robert Hooke for the hint.
+
+
 Version 8  10-Jan-2010
 ----------------------
 
index df3506cbf9381b1dd5569d91f445b98b158a948f..9916d47e9002792cab999581f1e01afa84b50797 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.65 for libjpeg 8.0.
+# Generated by GNU Autoconf 2.65 for libjpeg 8.0.1.
 #
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -698,8 +698,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='libjpeg'
 PACKAGE_TARNAME='libjpeg'
-PACKAGE_VERSION='8.0'
-PACKAGE_STRING='libjpeg 8.0'
+PACKAGE_VERSION='8.0.1'
+PACKAGE_STRING='libjpeg 8.0.1'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1430,7 +1430,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures libjpeg 8.0 to adapt to many kinds of systems.
+\`configure' configures libjpeg 8.0.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1501,7 +1501,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libjpeg 8.0:";;
+     short | recursive ) echo "Configuration of libjpeg 8.0.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1608,7 +1608,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libjpeg configure 8.0
+libjpeg configure 8.0.1
 generated by GNU Autoconf 2.65
 
 Copyright (C) 2009 Free Software Foundation, Inc.
@@ -1973,7 +1973,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by libjpeg $as_me 8.0, which was
+It was created by libjpeg $as_me 8.0.1, which was
 generated by GNU Autoconf 2.65.  Invocation command line was
 
   $ $0 $@
@@ -2905,7 +2905,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='libjpeg'
- VERSION='8.0'
+ VERSION='8.0.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -12675,7 +12675,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking libjpeg version number" >&5
 $as_echo_n "checking libjpeg version number... " >&6; }
 JPEG_LIB_VERSION=`sed -e '/^#define JPEG_LIB_VERSION/!d' -e 's/^[^0-9]*\([0-9][0-9]*\).*$/\1/' $srcdir/jpeglib.h`
-JPEG_LIB_VERSION="`expr $JPEG_LIB_VERSION / 10`:`expr $JPEG_LIB_VERSION % 10`"
+JPEG_LIB_VERSION="`expr $JPEG_LIB_VERSION / 10`:1"
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JPEG_LIB_VERSION" >&5
 $as_echo "$JPEG_LIB_VERSION" >&6; }
 
@@ -13215,7 +13215,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by libjpeg $as_me 8.0, which was
+This file was extended by libjpeg $as_me 8.0.1, which was
 generated by GNU Autoconf 2.65.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -13281,7 +13281,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-libjpeg config.status 8.0
+libjpeg config.status 8.0.1
 configured by $0, generated by GNU Autoconf 2.65,
   with options \\"\$ac_cs_config\\"
 
index c83e671e7396d0e15697fec2ebd965449dc26838..af8bfa131f9d3ae739e780ea4999f8519161e317 100644 (file)
@@ -5,7 +5,7 @@
 # Configure script for IJG libjpeg
 #
 
-AC_INIT([libjpeg], [8.0])
+AC_INIT([libjpeg], [8.0.1])
 
 # Directory where autotools helper scripts lives.
 AC_CONFIG_AUX_DIR([.])
@@ -309,7 +309,7 @@ AC_SUBST(MEMORYMGR)
 # Extract the library version ID from jpeglib.h.
 AC_MSG_CHECKING([libjpeg version number])
 [JPEG_LIB_VERSION=`sed -e '/^#define JPEG_LIB_VERSION/!d' -e 's/^[^0-9]*\([0-9][0-9]*\).*$/\1/' $srcdir/jpeglib.h`]
-[JPEG_LIB_VERSION="`expr $JPEG_LIB_VERSION / 10`:`expr $JPEG_LIB_VERSION % 10`"]
+[JPEG_LIB_VERSION="`expr $JPEG_LIB_VERSION / 10`:1"]
 AC_MSG_RESULT([$JPEG_LIB_VERSION])
 AC_SUBST([JPEG_LIB_VERSION])
 
index 563ab427163fd08c88d11a103f9d054049fdd1d2..639ce86f44fa204ba324231b907a0118c9435b39 100644 (file)
@@ -2,6 +2,7 @@
  * jcapimin.c
  *
  * Copyright (C) 1994-1998, Thomas G. Lane.
+ * Modified 2003-2010 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.
  *
@@ -73,6 +74,11 @@ jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
     cinfo->ac_huff_tbl_ptrs[i] = NULL;
   }
 
+  /* Must do it here for emit_dqt in case jpeg_write_tables is used */
+  cinfo->block_size = DCTSIZE;
+  cinfo->natural_order = jpeg_natural_order;
+  cinfo->lim_Se = DCTSIZE2-1;
+
   cinfo->script_space = NULL;
 
   cinfo->input_gamma = 1.0;    /* in case application forgets */
index 5284e588d6742e8cb2a9fb2dc590386458f62001..660883f459a26fa488f109c4568b55db0f8fbd60 100644 (file)
@@ -187,10 +187,6 @@ 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;
 }
 
 
index bdbde3454d82544fbfa5f24ea44581eefa024889..0ded9d574132feb341b1fbee706be3a678e98e2a 100644 (file)
@@ -2,6 +2,7 @@
  * jddctmgr.c
  *
  * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Modified 2002-2010 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.
  *
@@ -324,6 +325,7 @@ start_pass (j_decompress_ptr cinfo)
         * coefficients scaled by scalefactor[row]*scalefactor[col], where
         *   scalefactor[0] = 1
         *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
+        * We apply a further scale factor of 1/8.
         */
        FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
        int row, col;
@@ -337,7 +339,7 @@ start_pass (j_decompress_ptr cinfo)
          for (col = 0; col < DCTSIZE; col++) {
            fmtbl[i] = (FLOAT_MULT_TYPE)
              ((double) qtbl->quantval[i] *
-              aanscalefactor[row] * aanscalefactor[col]);
+              aanscalefactor[row] * aanscalefactor[col] * 0.125);
            i++;
          }
        }
index 0188ce3dfcd2ce2ebaa57c17da22101de01b6f2a..23ae9d333b749ce57c3c27dd6283d7461d46122d 100644 (file)
@@ -2,6 +2,7 @@
  * jidctflt.c
  *
  * Copyright (C) 1994-1998, Thomas G. Lane.
+ * Modified 2010 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.
  *
@@ -76,10 +77,9 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   FLOAT_MULT_TYPE * quantptr;
   FAST_FLOAT * wsptr;
   JSAMPROW outptr;
-  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+  JSAMPLE *range_limit = cinfo->sample_range_limit;
   int ctr;
   FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
-  SHIFT_TEMPS
 
   /* Pass 1: process columns from input, store into work array. */
 
@@ -152,12 +152,12 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
 
     z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
-    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
-    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
+    tmp10 = z5 - z12 * ((FAST_FLOAT) 1.082392200); /* 2*(c2-c6) */
+    tmp12 = z5 - z10 * ((FAST_FLOAT) 2.613125930); /* 2*(c2+c6) */
 
     tmp6 = tmp12 - tmp7;       /* phase 2 */
     tmp5 = tmp11 - tmp6;
-    tmp4 = tmp10 + tmp5;
+    tmp4 = tmp10 - tmp5;
 
     wsptr[DCTSIZE*0] = tmp0 + tmp7;
     wsptr[DCTSIZE*7] = tmp0 - tmp7;
@@ -165,8 +165,8 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     wsptr[DCTSIZE*6] = tmp1 - tmp6;
     wsptr[DCTSIZE*2] = tmp2 + tmp5;
     wsptr[DCTSIZE*5] = tmp2 - tmp5;
-    wsptr[DCTSIZE*4] = tmp3 + tmp4;
-    wsptr[DCTSIZE*3] = tmp3 - tmp4;
+    wsptr[DCTSIZE*3] = tmp3 + tmp4;
+    wsptr[DCTSIZE*4] = tmp3 - tmp4;
 
     inptr++;                   /* advance pointers to next column */
     quantptr++;
@@ -174,7 +174,6 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   }
   
   /* Pass 2: process rows from work array, store into output array. */
-  /* Note that we must descale the results by a factor of 8 == 2**3. */
 
   wsptr = workspace;
   for (ctr = 0; ctr < DCTSIZE; ctr++) {
@@ -187,8 +186,10 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     
     /* Even part */
 
-    tmp10 = wsptr[0] + wsptr[4];
-    tmp11 = wsptr[0] - wsptr[4];
+    /* Apply signed->unsigned and prepare float->int conversion */
+    z5 = wsptr[0] + ((FAST_FLOAT) CENTERJSAMPLE + (FAST_FLOAT) 0.5);
+    tmp10 = z5 + wsptr[4];
+    tmp11 = z5 - wsptr[4];
 
     tmp13 = wsptr[2] + wsptr[6];
     tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
@@ -209,31 +210,23 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
 
     z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
-    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
-    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
+    tmp10 = z5 - z12 * ((FAST_FLOAT) 1.082392200); /* 2*(c2-c6) */
+    tmp12 = z5 - z10 * ((FAST_FLOAT) 2.613125930); /* 2*(c2+c6) */
 
     tmp6 = tmp12 - tmp7;
     tmp5 = tmp11 - tmp6;
-    tmp4 = tmp10 + tmp5;
-
-    /* Final output stage: scale down by a factor of 8 and range-limit */
-
-    outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
-                           & RANGE_MASK];
-    outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
-                           & RANGE_MASK];
-    outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
-                           & RANGE_MASK];
-    outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
-                           & RANGE_MASK];
-    outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
-                           & RANGE_MASK];
-    outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
-                           & RANGE_MASK];
-    outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
-                           & RANGE_MASK];
-    outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
-                           & RANGE_MASK];
+    tmp4 = tmp10 - tmp5;
+
+    /* Final output stage: float->int conversion and range-limit */
+
+    outptr[0] = range_limit[((int) (tmp0 + tmp7)) & RANGE_MASK];
+    outptr[7] = range_limit[((int) (tmp0 - tmp7)) & RANGE_MASK];
+    outptr[1] = range_limit[((int) (tmp1 + tmp6)) & RANGE_MASK];
+    outptr[6] = range_limit[((int) (tmp1 - tmp6)) & RANGE_MASK];
+    outptr[2] = range_limit[((int) (tmp2 + tmp5)) & RANGE_MASK];
+    outptr[5] = range_limit[((int) (tmp2 - tmp5)) & RANGE_MASK];
+    outptr[3] = range_limit[((int) (tmp3 + tmp4)) & RANGE_MASK];
+    outptr[4] = range_limit[((int) (tmp3 - tmp4)) & RANGE_MASK];
     
     wsptr += DCTSIZE;          /* advance pointer to next row */
   }
index 4f76ae78fde619681004254fe77a5ea60852152b..8cb3d807fbb977a64b4d3cb7c6fbe6b053d37b26 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * jpegtran.c
  *
- * Copyright (C) 1995-2009, Thomas G. Lane, Guido Vollbeding.
+ * Copyright (C) 1995-2010, Thomas G. Lane, Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -63,18 +63,20 @@ usage (void)
 #ifdef C_PROGRESSIVE_SUPPORTED
   fprintf(stderr, "  -progressive   Create progressive JPEG file\n");
 #endif
-#if TRANSFORMS_SUPPORTED
   fprintf(stderr, "Switches for modifying the image:\n");
+#if TRANSFORMS_SUPPORTED
   fprintf(stderr, "  -crop WxH+X+Y  Crop to a rectangular subarea\n");
   fprintf(stderr, "  -grayscale     Reduce to grayscale (omit color data)\n");
   fprintf(stderr, "  -flip [horizontal|vertical]  Mirror image (left-right or top-bottom)\n");
   fprintf(stderr, "  -perfect       Fail if there is non-transformable edge blocks\n");
   fprintf(stderr, "  -rotate [90|180|270]         Rotate image (degrees clockwise)\n");
+#endif
   fprintf(stderr, "  -scale M/N     Scale output image by fraction M/N, eg, 1/8\n");
+#if TRANSFORMS_SUPPORTED
   fprintf(stderr, "  -transpose     Transpose image\n");
   fprintf(stderr, "  -transverse    Transverse transpose image\n");
   fprintf(stderr, "  -trim          Drop non-transformable edge blocks\n");
-#endif /* TRANSFORMS_SUPPORTED */
+#endif
   fprintf(stderr, "Switches for advanced users:\n");
   fprintf(stderr, "  -restart N     Set restart interval in rows, or in blocks with B\n");
   fprintf(stderr, "  -maxmemory N   Maximum memory to use (in kbytes)\n");
index 0c4e6ea6d5c432fb584947a885844dbdb1ba70d6..e7d1814dc1771ef9ba027faa98351799747bcbe0 100644 (file)
@@ -9,6 +9,6 @@
  */
 
 
-#define JVERSION       "8  10-Jan-2010"
+#define JVERSION       "8a  28-Feb-2010"
 
 #define JCOPYRIGHT     "Copyright (C) 2010, Thomas G. Lane, Guido Vollbeding"
diff --git a/rdbmp.c b/rdbmp.c
index f9711803f814100254bd5b0478c80cfa18f297dd..fd773d4bb5efba27a511383b3ca13bbc3f67dbce 100644 (file)
--- a/rdbmp.c
+++ b/rdbmp.c
@@ -2,7 +2,7 @@
  * rdbmp.c
  *
  * Copyright (C) 1994-1996, Thomas G. Lane.
- * Modified 2009 by Guido Vollbeding.
+ * Modified 2009-2010 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.
  *
@@ -178,10 +178,41 @@ get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
 }
 
 
+METHODDEF(JDIMENSION)
+get_32bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
+/* This version is for reading 32-bit pixels */
+{
+  bmp_source_ptr source = (bmp_source_ptr) sinfo;
+  JSAMPARRAY image_ptr;
+  register JSAMPROW inptr, outptr;
+  register JDIMENSION col;
+
+  /* Fetch next row from virtual array */
+  source->source_row--;
+  image_ptr = (*cinfo->mem->access_virt_sarray)
+    ((j_common_ptr) cinfo, source->whole_image,
+     source->source_row, (JDIMENSION) 1, FALSE);
+  /* Transfer data.  Note source values are in BGR order
+   * (even though Microsoft's own documents say the opposite).
+   */
+  inptr = image_ptr[0];
+  outptr = source->pub.buffer[0];
+  for (col = cinfo->image_width; col > 0; col--) {
+    outptr[2] = *inptr++;      /* can omit GETJSAMPLE() safely */
+    outptr[1] = *inptr++;
+    outptr[0] = *inptr++;
+    inptr++;                   /* skip the 4th byte (Alpha channel) */
+    outptr += 3;
+  }
+
+  return 1;
+}
+
+
 /*
  * This method loads the image into whole_image during the first call on
  * get_pixel_rows.  The get_pixel_rows pointer is then adjusted to call
- * get_8bit_row or get_24bit_row on subsequent calls.
+ * get_8bit_row, get_24bit_row, or get_32bit_row on subsequent calls.
  */
 
 METHODDEF(JDIMENSION)
@@ -224,6 +255,9 @@ preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
   case 24:
     source->pub.get_pixel_rows = get_24bit_row;
     break;
+  case 32:
+    source->pub.get_pixel_rows = get_32bit_row;
+    break;
   default:
     ERREXIT(cinfo, JERR_BMP_BADDEPTH);
   }
@@ -324,6 +358,9 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
     case 24:                   /* RGB image */
       TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight);
       break;
+    case 32:                   /* RGB image + Alpha channel */
+      TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight);
+      break;
     default:
       ERREXIT(cinfo, JERR_BMP_BADDEPTH);
       break;
@@ -377,6 +414,8 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
   /* Compute row width in file, including padding to 4-byte boundary */
   if (source->bits_per_pixel == 24)
     row_width = (JDIMENSION) (biWidth * 3);
+  else if (source->bits_per_pixel == 32)
+    row_width = (JDIMENSION) (biWidth * 4);
   else
     row_width = (JDIMENSION) biWidth;
   while ((row_width & 3) != 0) row_width++;