
                   PaintJet COLOR RASTER DUMP UTILITY
                             Mary Sue Rowan
                                11/25/87 
PRELIMINARY***************************IN PROGRESS************DO NOT 
COPY*************DO NOT DISTRIBUTE****************PRELIMINARY*******

     This report describes support for PaintJet (HP3630A) in BASIC 5.1.  
It consists of a CSUB utility for doing a color raster dump.  It is a color 
equivalent of the DUMP GRAPHICS functionality.  There is no "re-rasterization" 
of the picture (re-sizing in memory).

I.  Form
    The CSUB has the form of

    CSUB GDUMP_COLORED(FROM_DS, TO_DS, 
               OPTIONAL ROTATE$, INTEGER RESOLUTION, BACKGROUND$, ALGORITHM$)

    A.  Parameters
        1.  FROM_DS is the device whose frame buffer will be dumped.  There 
            is no default value; it is a required parameter.  It does not
            have to be the current "PLOTTER IS" device. 

        2.  TO_DS is the device (HPIB or RS232) address of the printer.  
            There is no default value; it is a required parameter.

        3.  ROTATE$ is an optional string parameter that has the possible 
            values of "NORMAL" and "ROTATE".  It determines whether the image 
            is to be rotated on the printed page.  The default value is  
            "NORMAL", or unrotated, meaning that the top of the screen is 
            oriented to the top of the printed page.

        4.  RESOLUTION is an optional integer parameter that corresponds to 
            the possible values of dot resolution for the device.  The default 
            value is 180 dots per inch (dpi). The other available value is 90 
            dpi.  If the parameter passed is greater than 90, then 180 is
            selected.  Otherwise the value is taken to be 90.

        5.  BACKGROUND$ is an optional string parameter with possible values of
            "ON" or "OFF".  The default value is "ON", meaning that for color 
            dumps, the background color (that assigned for PEN 0) will be 
            dumped.  "OFF" causes PEN 0 color to be assigned white, and thus 
            it will not be dumped.  This means that all PEN 0 pixels will now 
            be assigned white, even those that may be integral parts of the 
            picture, so care must be taken in using this option.  It has no 
            effect for dumps from monochrome crt's.

        6.  ALGORITHM$ is an optional string parameter with possible values of
            "DITHER" or "ERRDIF".  The default value is "DITHER", meaning that
            the algorithm used to create the dump employs dithering in a 2x2
            dither cell.  Each pixel expands to 4 dots on the printed page.
            "ERRDIF" causes the error diffusion algorithm to be employed.  Only
            one dot per pixel is output, so pictures are 1/4 the size of those
            printed with the dithered method.   

           
    B.  Use
        1.  User access:
            The CSUB can be loaded with 
                        
                         LOADSUB ALL FROM "GDUMP_C"
        
        2.  and called by, for example, 
         
                         CALL GDUMP_COLORED(25,702)            ! interactively 

            or,          Gdump_colored(CRT,701,"ROTATE", 90)   ! from a program
        
        3.  and deleted by
          
                         DELSUB GDUMP_COLORED
    
    C.  The utility will appear on the UTIL2 utility disc.
 
    D.  Considerations
        1.  Basic RESET
            When a dump is interrupted by a BASIC reset, there is no
            way of sending an "end raster graphics" escape code to the
            printer.  This means that if there is graphics data in 
            PaintJet's buffer, it will not get flushed until the next time
            the printer tries to write, so it could appear on the next
            printout.  A way to avoid this is to either allow a dump to
            complete normally, and thus have the proper escape sequences 
            sent to the printer, OR to cycle power on the printer before
            starting the next dump.
        
        2.  Color selection 
            A.  Dither algorithm:
                The color dump works by translating one pixel into a 2X2 
                dither cell, thus printing 4 dots for every pixel.  This means 
                that there are only 5 different intensity levels for each of 
                red, green, and blue.  This strategy yields a maximum of 125 
                different colors that the PaintJet will print.  In order for 
                PaintJet to tell the difference between two different colors, 
                they must differ in at least one of the rgb components so that 
                they fall into different intensity intervals for that component.  
                                   
                The intervals are 0-12%, 13-37%, 38-62%, 63-87%, and 88-100%.
                In other words, two reds with r=.90, g=0, b=0 and 
                r=.95, g=0, b=0 will look the same to the driver, but a third 
                one with an r=.85 will look different, because one less dot 
                in the dither cell will be "turned on".

            B.  Error diffusion:
                This is much more sensitive to shading differences, and the 
                potential difficulty described above should not arise.  The color 
                of a dot depends partially on the colors of dots around it, not
                solely on its absolute DAC value.  By "diffusion", we mean that
                some fractional DAC value is propagated to neighboring dots.
                For more information, see references to the Floyd-Steinberg
                error distribution algorithm in _Procedural Elements for
                Computer Graphics_, by David F. Rogers, McGraw-Hill, 1985.
                
        3.  Clipping of image
            Presently, the maximum resolution screen is 1280 X 1024 pixels
            (high resolution Catseye).  With the dither algorithm, this
            would mean a dump of 2560 x 2048  dots.  The maximum width of the 
            PaintJet is 1440 dots (at 180 dpi), so even a rotated dump of this 
            screen will have some clipping (608 dots or about 30%).  With
            the error diffusion algorithm, one dot per pixel would be output,
            so the 1280 x 1024 screen would all fit on a page, regardless of
            orientation. 

            For some suggested clip limits, see below.

        4.  Algorithm choice
            When choosing between algorithms, it is important to understand
            what the objectives are for the image.  

            The dither algorithm
                - does single pixel-wide lines extremely well,
                - can miss slight differences in shading,
                - will provide a smoother-grained texture, and
                - will clip a high resolution screen image.
            The error diffusion algorithm
                - will muddy single pixel-wide lines,
                - will pick up shading differences very well, 
                - will provide a coarser-grained texture, and
                - will not clip a high resolution screen image (at the default
                    printer resolution of 180 dpi).


            If the image has critical parts consisting of single pixel-wide
            lines, such as a slide or graph, choose dithering and appropriate
            clip limits (see below).  If color variation is important to the image, 
            choose error diffusion.
 

    D.  Performance
        1.  Cost of the driver:
            To estimate how much overhead the driver was costing, a program was written in
            BASIC to put data directly out to the printer, without actually trying
            to dump the display device.  The program put out exactly the number of
            dotrows of exactly the correct length to simulate various displays at
            various resolutions.  Then the driver was used to dump the display.
            The computer used was a 310.  Displays were of resolutions 512 x 400 (mr),
            and 1024 x 768 (hr).   Because the dither algorithm puts out 4 dots/pixel,
            and the error diffusion algorithm only 1 dot/pixel, an attempt to 
            correct for that is to print at 90 dpi (which quadruples the dots) for eda. 
            These are unrotated dumps.
 
            Dither algorithm at 180 dpi (printer resolution):

                          no driver   driver
             
                  hr       4:19        6:51
                  mr       1:30        1:56


            Error diffusion algorithm  

                          no driver   driver
                  dpi     180   90   180   90
             
                  hr      1:27 3:22  2:24 3:23  
                  mr      0:35 1:20  0:44 1:23 


            These results show that printing at 90 dpi is faster than printing
            the same size picture at 180 dpi.  They also show that the error
            diffusion algorithm has an advantage...
            Primarily, they show that there is a penalty for the driver paid in
            both cases, but as the resolution of the display increases, the overhead
            decreases for the error diffusion, indicating that the mechanical limits
            of the printer are being approached.


        2.  Performance limiters:
            SPU speed seems to be the main limiter in performance for the da, while
            the printer seems to be so for the eda.  The following
            table shows comparisons of different SPU's and the eda vs the da.

                 \  algorithm    error diff     dither     notes
                  \  dpi          180    90      180
              SPU  \      
              9836               0:43   1:21    1:53        68010 proc
               310               0:44   1:23    1:56        mr monitor
               320               0:33   1:21    1:29        mr monitor
               310               2:24   3:23    6:51        hr monitor
               350               1:23   3:23    3:57        hr monitor
               


        1.  Dither algorithm:
            Some rough timings were taken for dumping with and without the
            overhead of the driver.  Directly from BASIC, without the overhead 
            of a driver, using a 310 and a medium resolution monitor, using 
            3 plane color graphics, sending strings of characters of the same 
            size of buffers sent from the driver:   Time = 1:30 for the area of 
            a med res monitor (512 x 400), and 6:19 for the area of a hi-res 
            monitor (1024 x 768).  With the driver, time is 1:59 for med-res 
            and 6:51 for hi-res.  These are for unrotated dumps.
             
            On a 320, the time for the dump with the driver was 1:29 with
            the medium resolution display.  On a 9836C, with a 68010 processor, 
            the time for the dump with the driver was 1:55.  On a 350, with
            a high res monitor and the driver, the time was 4:16.

    E.  Manual Writers
        Please emphasize to customers:

        1.  With the dither algorithm (default), they will not get 100% 
            of their dump for high resolution screens, if the image is
            not rotated, the right hand side of the screen will be clipped.
            Workaround:

            a.  Rotate the picture, to get as much as possible on the page.
                At the same time, arrange the picture to have the most vital
                parts of it (such as a title) a little farther down on the
                screen (away from the top), as even the top of the picture
                will get clipped in this case.

            b.  Rotate the picture, and use the following clip limits:
                Monitor resolution=1024 x 768
                   Use  VIEWPORT 0,124,0,93
                   and specify "ROTATE", 180 dpi, and "DITHER" algorithm.
                
                For monitors of other resolutions, experiment with the
                VIEWPORT statement to find the one that works best for
                their situation. 
                
            c.  Use the error diffusion algorithm.
                

        2.  With the dither algorithm (default), slight differences in 
            shading will likely be lost because of the dithering technique 
            used.  Workaround:  

            a.  Make sure that colors requiring differentiation are at least
                20% different in their DAC values in the red, green, or blue
                dimension, so that the driver will cause them to be printed
                differently, or arrange the DAC values so that they fall in
                different intervals (given earlier).
               
            b.  Use the error diffusion algorithm.


II.  Internals
     A.  General description

         1.  PaintJet requirements
             For PaintJet to print in color, multiple color "planes" must
             be enabled.  Because the data from the system color map comes
             in rgb values, it was most convenient to have 3 "planes" for
             PaintJet, and thus get 8 basic colors.  Dithering can provide
             the added colors.  A dotrow of data must be sent for each plane,
             before the carriage can be advanced to the next dotrow.
           
         2.  PaintJet is capable of doing its own dithering at certain 
             resolutions.  This capability was not utilized by the driver, 
             however, because it is only activated at certain resolutions, 
             and it was desirable to permit users to access the full scope of 
             resolutions on these devices.

     B.  Dithering Algorithm
             
         1.  A 2x2 dither cell was selected for implementation, because with
             it, a total of 125 colors is possible, and that seemed sufficient
             for most applications.  Dither algorithms for 2x2 cells are
             inherently simpler than for larger cells, also it was more 
             practical for size purposes.  With a 2x2 dither cell, a rotated 
             dump of a high resolution monitor will almost fit on the 
             printed page for the PaintJet. 
           
         2.  12 bits per pixel!
             Expanding each pixel to four dots, and having 3 color planes
             requires that 12 bits of information be sent per pixel.  It 
             means that bytes in the buffer must be packed so that the
             top half of a dither cell (2 bits) for four pixels fits into
             a byte in one buffer, and another buffer has the lower half of
             the dither cell for each of those four pixels.  So, for every
             row of pixels on the screen, six buffers of information are
             sent to the printer (2 dotrows with 3 color planes each).
         
        4.  Algorithm
            The CSUB consists of a shell written in MODCAL.  This shell
            determines the type of device, and does the color map 
            transformation if necessary.  The main work of the utility is
            done by a 4 assembler routines.  One each for color rotated,
            b&w rotated, color unrotated and b&w unrotated.  Each invocation
            of a color routine does the processing for one row of pixels. 
            Each invocation of a monochromatic routine does the processing
            for two rows of pixels. 

            If a color device is present, the system color map is examined, 
            and a mapping of the colors in the color map to the 125 possible 
            squirt colors is performed.  Note that this mapping may be many 
            to one. 

            When the device is identified and the color map is examined,
            then the dump begins.  For the normal (unrotated) dump, the 
            gdump_red_c routine is called for each row of pixels in the frame
            buffer, beginning with the top row.  This routine examines each 
            pixel, from left to right.  A pixel is examined, the color map 
            index extracted, and the mapping to the PaintJet color map is made.  
            For each four pixels that are examined, six bytes of information 
            are generated, one for each of the six buffers sent per row of 
            pixels (see # 3 above). 
           
            For the rotated dump, the gdump_c routine is called for each 
            column of pixels in the frame buffer, beginning with the left side 
            of the screen.  
       
            For dumps from monochromatic display devices, the color map 
            transformation is not done, and the driver calls the assembler 
            routines that are essentially identical to the ones used by 
            DUMP GRAPHICS and GDUMP_ROTATED (a CSUB) statements.  The main
            difference is that 4 dots per pixel are printed, so that the 
            monochromatic dumps will be the same size as the color dumps
            from displays of comparable resolution. 
        
    B.  Data structures 
        1.   pixrow : array [1..2,1..3] of bigbufstrtype.
             The six buffers which get filled for every pixel row.
             This is for color only.  

        2.   dgbuff : dblbufstrtype.
             This is essentially the equivalent of pixrow for the mono
             dump, except it is a double length buffer because the mono
             dump routines put out two rows of information with each invocation. 
       
        3.   xmap : array [0..255] of 1..125.
             Each entry correlates to the entry of the same index in the
             system color map.  xmap[i] contains the index into sqtcmap,
             which would contain the dither patterns for red, green and blue 
             that will match as closely as possible syscmap[i].  
           
        4.   sqtcmap : array [1..125,1..3] of 0..15.
             An array that contains the 125 colors of PaintJet for the
             2x2 dither cell.  The column index refers to rgb values.
             The 0..15 value refers to the 4 bits/pixel or the 2x2 dither
             cell.  The msb and next bit refer to the first dot row, and
             the third bit and lsb refer to the second dot row. Possible
             values are 0,7,8,9,15. 

III.  Limitations
      A.  Striping
             There is an apparent striping effect for large areas of
             color, especially in the dithered case, where dots are 
             more sparsly distributed (e.g., one or two dots per dither
             cell).  This is caused by inaccuracies in the mechanism for
             the carriage return, so that there is some overlap of ink 
             between dotrows.  It can be seen even in the case of
             solid colors, but it is accentuated by the dither pattern.  
             The user can avoid this by enabling dithering from software 
             (using BASIC AREA INTENSITY).  This seems to break up the 
             striping effect.  The newer revisions of the printer have
             minimized this problem.
         
      B.  Speed
             There is a small price paid for the overhead of the driver.
             This could be improved by tuning the assembler routines.
             It might become necessary if future printers are capable of much
             faster dumping.       
   
