-
Bug
-
Resolution: Fixed
-
P3
-
1.4.0, 1.4.2
-
b77
-
generic, x86
-
generic, windows_xp
The current Java 2D printing implementation (up to and including 1.4/merlin)
could be more efficient in printing images which use less than 24 bpp.
In general the less bpp in the source image, the more inefficient the
implementation.
Name: pr15447 Date: 01/22/2004
FULL PRODUCT VERSION :
A DESCRIPTION OF THE PROBLEM :
When printing large images, for example full page 200dpi images, which is common when attempting to overlay text on a form 'image', to replace pre-printed forms, the JVM consumes more memory than needed under Windows. Other platforms may have the same issue.
The excess memory consumption is because the new printing engine attempts to send the Image directly to the printer graphics if it can, avoiding the use of the rasterizer, but during the sending of the image it creates a new BufferedImage, using the same size of the original image, with a type of TYPE_3BYTE_BGR, even if the original image is of the same type. The offending code is in WPathGraphics.drawImageToGDI().
For example, a binary full page form at 200dpi, should consume (8.5*11*200*200/(8 pixels per byte)) = 880k.
But the temporary 3BYTE_BGR image consumes (8.5*11*200*200*3) = 11.2 MB.
At a minimum, it should not create a temp image if the source image is of the needed type, but maybe it should not use a temp image at all, and the native BGR to DIB routine in WPrinterJob.cpp should be enhanced to understand several common formats (INT_RGB, BYTE_RGB, BYTE_GRAY, BYTE_BINARY). Or, if it MUST use a temp image, then send it to the DIB in chunks, so the memory consumption is minimized.
It seems that the internal graphics loop in the JDK does MANY image conversions in many cases (screen, print, and BufferedImage graphics)... maybe there should be a common optimized format to avoid all of the image conversions?
See the workaround section for the memory usage differences.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
use any windows print service to print a large image
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
force the printing engine to use the rasterizer by setting
sun.java2d.print.pipeline=raster
but then the image printing is much slower, and the print jobs are much larger, 67 MB vs. 13.5 MB.
With a test 200dpi binary image of 1696x2800, (a 61k TIFF file)...
When using the rasterizer, I can print a full page image using a test program with a heap setting of -mx12m, in 16 seconds. If I increase the heap to 196m, it prints in 16 seconds.
If I don't use the rasterizer, the same program with the same image requires setting -mx72m !!!!, but it prints in 14 seconds. If I increase the heap size to 128m, it prints in 11 seconds.
If I convert the BYTE_BINARY image to a BYTE_GRAY before printing...
using the rasterizer requires a heap setting of 40m, and it prints in 16 seconds. with a heap setting of 196m, it prints in 16 seconds.
using direct to GDI requires a heap setting of 24m, and it prints in 4 seconds !!! with a heap setting of 196m, it prints in 4 seconds.
Amazingly, the BYTE_GRAY image requires LESS memory to print than the BYTE_BINARY, even though the BYTE_BINARY is 1/8 the size in memory! This again is probably due to intermediate image conversions because of the packed multi-pixel per byte structure.
(Review ID: 230355)
======================================================================
could be more efficient in printing images which use less than 24 bpp.
In general the less bpp in the source image, the more inefficient the
implementation.
Name: pr15447 Date: 01/22/2004
FULL PRODUCT VERSION :
A DESCRIPTION OF THE PROBLEM :
When printing large images, for example full page 200dpi images, which is common when attempting to overlay text on a form 'image', to replace pre-printed forms, the JVM consumes more memory than needed under Windows. Other platforms may have the same issue.
The excess memory consumption is because the new printing engine attempts to send the Image directly to the printer graphics if it can, avoiding the use of the rasterizer, but during the sending of the image it creates a new BufferedImage, using the same size of the original image, with a type of TYPE_3BYTE_BGR, even if the original image is of the same type. The offending code is in WPathGraphics.drawImageToGDI().
For example, a binary full page form at 200dpi, should consume (8.5*11*200*200/(8 pixels per byte)) = 880k.
But the temporary 3BYTE_BGR image consumes (8.5*11*200*200*3) = 11.2 MB.
At a minimum, it should not create a temp image if the source image is of the needed type, but maybe it should not use a temp image at all, and the native BGR to DIB routine in WPrinterJob.cpp should be enhanced to understand several common formats (INT_RGB, BYTE_RGB, BYTE_GRAY, BYTE_BINARY). Or, if it MUST use a temp image, then send it to the DIB in chunks, so the memory consumption is minimized.
It seems that the internal graphics loop in the JDK does MANY image conversions in many cases (screen, print, and BufferedImage graphics)... maybe there should be a common optimized format to avoid all of the image conversions?
See the workaround section for the memory usage differences.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
use any windows print service to print a large image
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
force the printing engine to use the rasterizer by setting
sun.java2d.print.pipeline=raster
but then the image printing is much slower, and the print jobs are much larger, 67 MB vs. 13.5 MB.
With a test 200dpi binary image of 1696x2800, (a 61k TIFF file)...
When using the rasterizer, I can print a full page image using a test program with a heap setting of -mx12m, in 16 seconds. If I increase the heap to 196m, it prints in 16 seconds.
If I don't use the rasterizer, the same program with the same image requires setting -mx72m !!!!, but it prints in 14 seconds. If I increase the heap size to 128m, it prints in 11 seconds.
If I convert the BYTE_BINARY image to a BYTE_GRAY before printing...
using the rasterizer requires a heap setting of 40m, and it prints in 16 seconds. with a heap setting of 196m, it prints in 16 seconds.
using direct to GDI requires a heap setting of 24m, and it prints in 4 seconds !!! with a heap setting of 196m, it prints in 4 seconds.
Amazingly, the BYTE_GRAY image requires LESS memory to print than the BYTE_BINARY, even though the BYTE_BINARY is 1/8 the size in memory! This again is probably due to intermediate image conversions because of the packed multi-pixel per byte structure.
(Review ID: 230355)
======================================================================