Bug 694970 - tiffscaled* device does not take downscaling further than 8?
Summary: tiffscaled* device does not take downscaling further than 8?
Status: RESOLVED FIXED
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: Other Driver (show other bugs)
Version: master
Hardware: PC Linux
: P4 enhancement
Assignee: Robin Watts
URL:
Keywords:
Depends on: 694773
Blocks:
  Show dependency tree
 
Reported: 2014-01-24 00:33 UTC by Hin-Tak Leung
Modified: 2015-12-22 09:25 UTC (History)
1 user (show)

See Also:
Customer:
Word Size: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hin-Tak Leung 2014-01-24 00:33:36 UTC
Tried to look for some way to render at 1200 dpi of a A0 document and not suck at it. That's about 40,000 x 56,000 pixels with colours. Equivalent to a 6.7 GB ppmraw.

The background is that RTL has a device-specific resolution (Bug 694950) and 
-r<anything_else> mis-renders and looks wrong. x11 at -r72 is not even close to corect, besides the file needs something like -r20 to be seen on a normal screen in full.

But 6.7 GB ppmraw  equivalent is quite painful to handle. So the down-sampling devices (tiffscaled*) seems useful and appropriate, but it didn't take anything higher than 8. Actually it didn't seem to be the device, but the interpreter didn't like it and bailed with the unhelp error -995 and flush to end.

Ideally -dDownScaleFactor=64 (8 and a further 8, as in attachment 10610 [details]) would be
nice...  

This is about a pcl input file, the tiffscaled* devices probably belong somewhere in ghostscript, just not very sure whether it should be images or graphics library.
Comment 1 Robin Watts 2014-01-24 03:24:30 UTC
The problem is that DownScaleFactor=32 and 34 have special meanings to the downscaler.

If you look in gxdownscale.c at the decode_factor function, you can probably test some changes.

Change '32' to '320' and '34' to '340'. This moves our two special values up a bit.

Then search in that file for "if (factor > 8)". It should occur 3 times. Change that to "if (factor > 256)" in all 3 cases.

Hopefully now the downscaler should be able to downscale as you require.

Let me know how you get on.
Comment 2 Hin-Tak Leung 2014-01-24 06:50:37 UTC
(In reply to comment #1)
> The problem is that DownScaleFactor=32 and 34 have special meanings to the
> downscaler.
...

The problem isn't even about those - looking at my command history, I was only trying 12, 16 and 18.

 -dDownScaleFactor=16 -r600 
 -dDownScaleFactor=12 -r600 
 -dDownScaleFactor=18 -r900
 -dDownScaleFactor=16 -r800 

pcl6 in its typically unhelpful message just says error -995 and flush to end.

I'll have a go at modifying gxdownscale.c at some point; but the test file is as  in Bug 694950 - without my wip diff, the only difference is you won't see the (currently rather broken) background image.
Comment 3 Hin-Tak Leung 2014-01-24 06:54:14 UTC
Also the documentation is lacking - it just says "small integers" at a few places, no mention of 32/34 or any values being special.
Comment 4 Hin-Tak Leung 2014-01-24 07:17:47 UTC
Suggests using -32 / -34 (negative values) to mean special treatment, as whatever large number (320, 340) somebody might try it one day...
Comment 5 Robin Watts 2014-01-24 08:00:42 UTC
Sorry, to be clearer... the problem *with simply raising the maximum downscale* is that we have preexisting special values of 32 and 34. These are defined in gs/doc/Devices.html in the tiffsep section.

If we are prepared to break existing callers, then we can change these values.

But a downscale factor of 8 would mean that an 8x8 area will be compressed into a single pixel; any greater than 8x8, and any given single pixel will contribute less accuracy than an 8 bit output can hold, so seems a bit pointless.

I will try to test this at some point, but it won't be in the immediate future. If you beat me to it, put a note on the bug, and I'll discuss it with my colleagues to see whether it's worth breaking existing callers.
Comment 6 Hin-Tak Leung 2014-01-24 09:28:09 UTC
If 33 works, it is probably not important that 32 and 34 are special - but the documentation is certainly lacking. Should have it when the -ddownscalefactor is mentioned. 

The purpose of doing 64x64 isn't about accucracy - it is about having a rough preview of manageable size. That file at 8x8 is still 35 mega pixels.
Comment 7 Hin-Tak Leung 2014-01-24 17:52:10 UTC
Created attachment 10616 [details]
1200 dpi downscale by factor=64.

tiff file output 1200 dpi downscale by factor=64.

need marked private.

For comparison with the 8x then 13% with image viewer.
It seems a few times slower than 8x though. (almost 3 hours?, 8x was already an hour and half).

Generated with this diff - (obviously if you care about how it currently works with special values of 32/34, you cannot apply it as shown):

diff --git a/gs/base/gxdownscale.c b/gs/base/gxdownscale.c
index 1e78638..106b072 100644
--- a/gs/base/gxdownscale.c
+++ b/gs/base/gxdownscale.c
@@ -1519,9 +1519,9 @@ static void down_core32(gx_downscaler_t *ds,
 
 static void decode_factor(int factor, int *up, int *down)
 {
-    if (factor == 32)
+    if (factor == 320)
         *down = 3, *up = 2;
-    else if (factor == 34)
+    else if (factor == 340)
         *down = 3, *up = 4;
     else
         *down = factor, *up = 1;
@@ -1605,15 +1605,15 @@ int gx_downscaler_init_planar(gx_downscaler_t      *ds,
         }
     }
 
-    if ((src_bpc == 8) && (dst_bpc == 8) && (factor == 32))
+    if ((src_bpc == 8) && (dst_bpc == 8) && (factor == 320))
     {
         core = &down_core8_3_2;
     }
-    else if ((src_bpc == 8) && (dst_bpc == 8) && (factor == 34))
+    else if ((src_bpc == 8) && (dst_bpc == 8) && (factor == 340))
     {
         core = &down_core8_3_4;
     }
-    else if (factor > 8)
+    else if (factor > 256)
     {
         code = gs_note_error(gs_error_rangecheck);
         goto cleanup;
@@ -1719,7 +1719,7 @@ int gx_downscaler_init(gx_downscaler_t   *ds,
     ds->src_bpc    = src_bpc;
     
     /* Choose an appropriate core */
-    if (factor > 8)
+    if (factor > 256)
     {
         code = gs_note_error(gs_error_rangecheck);
         goto cleanup;
@@ -2142,7 +2142,7 @@ int gx_downscaler_process_page(gx_device                 *dev,
     arg.ds.num_planes = 0;
 
     /* Choose an appropriate core */
-    if (factor > 8)
+    if (factor > 256)
     {
         return gs_note_error(gs_error_rangecheck);
     }
Comment 8 Hin-Tak Leung 2014-01-28 05:13:29 UTC
The initial problem seems to be due to fix to bug 694773 (default raster resolution to the PJL setting) does not work completely. I have another test file so will file another.
Comment 9 Robin Watts 2015-12-22 09:25:16 UTC
Docs improved in:

commit dd43cb649f5772096b71c23f1bf36982531b74fa
Author: Robin Watts <robin.watts@artifex.com>
Date:   Tue Dec 22 17:21:37 2015 +0000

    Bug 694970: Improve downscaler docs.

    Mention the explicit limit for DownScaleFactor.

    There is no point in downscaling by more than 8, as any given
    pixel ceases to contribute enough to make a difference.

    At any rate, any downscale scale >= 12 runs the risk of overflowing
    the 32bit integers used to do the sum.

I do not propose to raise the limit, because I just can't see the point.