home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / sharewar / dos / program / gs300sr1 / gs300sr1.exe / GSIMAGE1.C < prev    next >
C/C++ Source or Header  |  1994-07-27  |  17KB  |  575 lines

  1. /* Copyright (C) 1989, 1992, 1993, 1994 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* gsimage1.c */
  20. /* Image procedures for Ghostscript library */
  21. /* This file is logically part of gsimage.c; we have split it out */
  22. /* to reduce the code working set. */
  23. #include "gx.h"
  24. #include "memory_.h"
  25. #include "gpcheck.h"
  26. #include "gserrors.h"
  27. #include "gxfixed.h"
  28. #include "gxarith.h"
  29. #include "gxmatrix.h"
  30. #include "gscspace.h"
  31. #include "gsccolor.h"
  32. #include "gspaint.h"
  33. #include "gzstate.h"
  34. #include "gxcmap.h"
  35. #include "gzpath.h"
  36. #include "gxcpath.h"
  37. #include "gxdevmem.h"
  38. #include "gximage.h"
  39. #include "gzht.h"
  40. #include "gzdraw.h"
  41.  
  42. /* Process the next piece of an image */
  43. int
  44. gs_image_next(register gs_image_enum *penum, const byte *dbytes, uint dsize,
  45.   uint *pused)
  46. {    uint rsize = penum->bytes_per_row;
  47.     uint pos = penum->byte_in_row;
  48.     int width = penum->width;
  49.     int nplanes = penum->num_planes;
  50.     uint dleft = dsize;
  51.     uint dpos = 0;
  52.     gs_state *pgs = penum->pgs;
  53.     gx_device *save_dev = 0;
  54.     fixed xcur_save, ycur_save;
  55.     int y_save;
  56.     int code;
  57.     /* Accumulate separated colors, if needed */
  58.     if ( penum->plane_index != 0 )
  59.       if ( dsize != penum->planes[0].size )
  60.         return_error(gs_error_undefinedresult);
  61.     penum->planes[penum->plane_index].data = dbytes;
  62.     penum->planes[penum->plane_index].size = dsize;
  63.     if ( ++(penum->plane_index) != nplanes )
  64.         return 0;
  65.     penum->plane_index = 0;
  66.     /* Save the dynamic state components in case of an error. */
  67.     xcur_save = penum->xcur;
  68.     ycur_save = penum->ycur;
  69.     y_save = penum->y;
  70.     /* We've accumulated an entire set of planes. */
  71.     if ( !penum->never_clip )
  72.        {    /* Install the clipping device if needed. */
  73.         gx_device_clip *cdev = penum->clip_dev;
  74.         save_dev = gs_currentdevice(pgs);
  75.         cdev->target = save_dev;
  76.         gx_set_device_only(pgs, (gx_device *)cdev);
  77.        }
  78.     while ( dleft )
  79.        {    /* Fill up a row, then display it. */
  80.         uint bcount = min(dleft, rsize - pos);
  81.         int px;
  82.         for ( px = 0; px < nplanes; px++ )
  83.           (*penum->unpack)(penum, &penum->map[px],
  84.                    penum->buffer + (px << penum->log2_xbytes),
  85.                    penum->planes[px].data + dpos, bcount, pos);
  86.         pos += bcount;
  87.         dpos += bcount;
  88.         dleft -= bcount;
  89.         if ( pos == rsize )    /* filled an entire row */
  90.            {
  91. #ifdef DEBUG
  92. if ( gs_debug_c('B') )
  93.    {            int i, n = width * penum->spp;
  94.             dputs("[B]row:");
  95.             for ( i = 0; i < n; i++ )
  96.                 dprintf1(" %02x", penum->buffer[i]);
  97.             dputs("\n");
  98.    }
  99. #endif
  100.             if ( !penum->skewed )
  101.               { /* Precompute integer y and height, */
  102.                 /* and check for clipping. */
  103.                 fixed yc = penum->ycur, yn;
  104.                 fixed dyy = penum->fyy;
  105.                 fixed adjust = penum->adjust;
  106.                 if ( dyy > 0 )
  107.                   dyy += adjust << 1,
  108.                   yc -= adjust;
  109.                 else
  110.                   dyy = (adjust << 1) - dyy,
  111.                   yc -= dyy - adjust;
  112.                 if ( yc >= penum->clip_box.q.y ) goto mt;
  113.                 yn = yc + dyy;
  114.                 if ( yn <= penum->clip_box.p.y ) goto mt;
  115.                 penum->yci = fixed2int_var_rounded(yc);
  116.                 penum->hci =
  117.                   fixed2int_var_rounded(yn) - penum->yci;
  118.                 if ( penum->hci == 0 ) goto mt;
  119.               }
  120.             code = (*penum->render)(penum, penum->buffer, width * penum->spp, 1);
  121.             if ( code < 0 ) goto err;
  122. mt:            if ( ++(penum->y) == penum->height ) goto end;
  123.             pos = 0;
  124.             penum->xcur += penum->fyx;
  125.             penum->ycur += penum->fyy;
  126.            }
  127.        }
  128.     penum->byte_in_row = pos;
  129.     code = 0;
  130.     goto out;
  131. end:    /* End of data */
  132.     code = 1;
  133.     goto out;
  134. err:    /* Error or interrupt, restore original state. */
  135.     penum->plane_index = penum->spread - 1;
  136.     penum->xcur = xcur_save;
  137.     penum->ycur = ycur_save;
  138.     penum->y = y_save;
  139.     /* Note that caller must call gs_image_cleanup */
  140.     /* for both error and normal termination. */
  141. out:    if ( save_dev != 0 )
  142.         gx_set_device_only(pgs, save_dev);
  143.     if ( code >= 0 )
  144.         *pused = dpos;
  145.     return code;
  146. }
  147.  
  148. /* Clean up by releasing the buffers. */
  149. void
  150. gs_image_cleanup(register gs_image_enum *penum)
  151. {    gs_memory_t *mem = penum->pgs->memory;
  152.     gs_free_object(mem, penum->clip_dev, "image clipper");
  153.     penum->clip_dev = 0;
  154.     gs_free_object(mem, penum->line, "image line");
  155.     penum->line = 0;
  156.     gs_free_object(mem, penum->buffer, "image buffer");
  157.     penum->buffer = 0;
  158. }
  159.  
  160. /* ------ Unpacking procedures ------ */
  161.  
  162. void
  163. image_unpack_1(const gs_image_enum *penum, const sample_map *pmap,
  164.   byte *bptr, register const byte *data, uint dsize, uint inpos)
  165. {    register bits32 *bufp = (bits32 *)(bptr + (inpos << 3));
  166.     int left = dsize;
  167.     register const bits32 *map = &pmap->table.lookup4x1to32[0];
  168.     register uint b;
  169.     if ( left & 1 )
  170.        {    b = data[0];
  171.         bufp[0] = map[b >> 4];
  172.         bufp[1] = map[b & 0xf];
  173.         data++, bufp += 2;
  174.        }
  175.     left >>= 1;
  176.     while ( left-- )
  177.        {    b = data[0];
  178.         bufp[0] = map[b >> 4];
  179.         bufp[1] = map[b & 0xf];
  180.         b = data[1];
  181.         bufp[2] = map[b >> 4];
  182.         bufp[3] = map[b & 0xf];
  183.         data += 2, bufp += 4;
  184.        }
  185. }
  186.  
  187. void
  188. image_unpack_2(const gs_image_enum *penum, const sample_map *pmap,
  189.   byte *bptr, register const byte *data, uint dsize, uint inpos)
  190. {    register bits16 *bufp = (bits16 *)(bptr + (inpos << 2));
  191.     int left = dsize;
  192.     register const bits16 *map = &pmap->table.lookup2x2to16[0];
  193.     while ( left-- )
  194.        {    register unsigned b = *data++;
  195.         *bufp++ = map[b >> 4];
  196.         *bufp++ = map[b & 0xf];
  197.        }
  198. }
  199.  
  200. void
  201. image_unpack_4(const gs_image_enum *penum, const sample_map *pmap,
  202.   byte *bptr, register const byte *data, uint dsize, uint inpos)
  203. {    register int spread = penum->spread;
  204.     register byte *bufp = bptr + (inpos << 1) * spread;
  205.     int left = dsize;
  206.     register const byte *map = &pmap->table.lookup8[0];
  207.     while ( left-- )
  208.        {    register unsigned b = *data++;
  209.         *bufp = map[b >> 4]; bufp += spread;
  210.         *bufp = map[b & 0xf]; bufp += spread;
  211.        }
  212. }
  213.  
  214. void
  215. image_unpack_8(const gs_image_enum *penum, const sample_map *ignore_pmap,
  216.   byte *bptr, const byte *data, uint dsize, uint inpos)
  217. {    byte *bufp = bptr + inpos;
  218.     if ( data != bufp ) memcpy(bufp, data, dsize);
  219. }
  220.  
  221. /* ------ Rendering procedures ------ */
  222.  
  223. /* Rendering procedure for ignoring an image.  We still need to iterate */
  224. /* over the samples, because the procedure might have side effects. */
  225. int
  226. image_render_skip(gs_image_enum *penum, byte *data, uint w, int h)
  227. {    return h;
  228. }
  229.  
  230. /* Rendering procedure for a monobit image with no */
  231. /* skew or rotation and pure colors. */
  232. int
  233. image_render_simple(gs_image_enum *penum, byte *buffer, uint w, int h)
  234. {    byte *line = penum->line;
  235.     uint line_size, line_width;
  236.     gx_device *dev = gs_currentdevice(penum->pgs);
  237.     dev_proc_copy_mono((*copy_mono)) = dev_proc(dev, copy_mono);
  238.     int ix = fixed2int_rounded(penum->xcur);
  239.     const int iy = penum->yci, ih = penum->hci;
  240.     gx_color_index
  241.         zero = penum->icolor0.colors.pure,
  242.         one = penum->icolor1.colors.pure;
  243.     int dy;
  244.  
  245.     if ( penum->map[0].table.lookup4x1to32[0] != 0 )
  246.         zero = penum->icolor1.colors.pure,
  247.         one = penum->icolor0.colors.pure;
  248.  
  249.     if ( line == 0 )
  250.     {    /* A direct BitBlt is possible. */
  251.         line = buffer;
  252.         line_size = (w + 7) >> 3;
  253.         line_width = w;
  254.     }
  255.     else
  256.     {    fixed xl = penum->xcur + fixed_half - int2fixed(ix);
  257.         const fixed dxx = penum->fxx;
  258.         const fixed dxx_4 = dxx << 2;
  259.         const fixed dxx_8 = dxx_4 << 1;
  260.         register const byte *psrc = buffer;
  261.         byte sbit = 0x80;
  262.         byte *endp = buffer + (w >> 3);
  263.         const byte endbit = 1 << (~w & 7);
  264.         byte data;
  265.  
  266.         line_size = penum->line_size;
  267.         line_width = penum->line_width;
  268.         if ( dxx < 0 )
  269.             ix -= line_width,
  270.             xl += int2fixed(line_width);
  271.  
  272.         /* Invert the bit following the last valid data bit. */
  273.         if ( endbit == 0x80 ) *endp = ~endp[-1] << 7;
  274.         else if ( *endp & (endbit << 1) ) *endp &= ~endbit;
  275.         else *endp |= endbit;
  276.         data = *psrc;
  277.  
  278.         memset(line, 0, line_size);
  279.         /*
  280.          * Loop invariants:
  281.          *    data = *psrc;
  282.          *    sbit = 1 << n, 0<=n<=7.
  283.          */
  284.         do
  285.         {    int x0, n, bit;
  286.             byte *bp;
  287.             static const byte lmasks[9] =
  288.              { 0xff, 0x7f, 0x3f, 0x1f, 0xf, 7, 3, 1, 0 };
  289.             static const byte rmasks[8] =
  290.              { 0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
  291.  
  292.             /* Scan a run of zeros. */
  293.             while ( ~data & sbit )
  294.             {    xl += dxx;
  295.                 sbit >>= 1;
  296.             }
  297.             if ( !sbit )
  298.             {    while ( (data = *++psrc) == 0 )
  299.                     xl += dxx_8;
  300.                 if ( data > 0xf )
  301.                     sbit = 0x80;
  302.                 else
  303.                     xl += dxx_4,
  304.                     sbit = 0x08;
  305.                 while ( ~data & sbit )
  306.                 {    xl += dxx;
  307.                     sbit >>= 1;
  308.                 }
  309.             }
  310.             if ( !(psrc < endp || sbit > endbit) )
  311.                 break;
  312.             x0 = fixed2int_var(xl);
  313.  
  314.             /* Scan a run of ones. */
  315.             while ( data & sbit )
  316.             {    xl += dxx;
  317.                 sbit >>= 1;
  318.             }
  319.             if ( !sbit )
  320.             {    while ( (data = *++psrc) == 0xff )
  321.                     xl += dxx_8;
  322.                 if ( data < 0xf0 )
  323.                     sbit = 0x80;
  324.                 else
  325.                     xl += dxx_4,
  326.                     sbit = 0x08;
  327.                 while ( data & sbit )
  328.                 {    xl += dxx;
  329.                     sbit >>= 1;
  330.                 }
  331.             }
  332.  
  333.             /* Fill the run in the scan line. */
  334.             n = fixed2int_var(xl) - x0;
  335.             if ( n < 0 ) x0 += n, n = -n;
  336.             bp = line + (x0 >> 3);
  337.             bit = x0 & 7;
  338.             if ( (n += bit) <= 8 )
  339.                 *bp |= lmasks[bit] - lmasks[n];
  340.             else
  341.             {    *bp++ |= lmasks[bit];
  342.                 if ( n > 64 )
  343.                 {    int nb = (n >> 3) - 1;
  344.                     memset(bp, 0xff, nb);
  345.                     bp += nb;
  346.                     n &= 7;
  347.                 }
  348.                 else
  349.                 {    n -= 8;
  350.                     while ( (n -= 8) >= 0 )
  351.                         *bp++ = 0xff;
  352.                 }
  353.                 *bp |= rmasks[n & 7];
  354.             }
  355.  
  356.         } while ( psrc < endp || sbit > endbit );
  357.     }
  358.  
  359.     /* Finally, transfer the scan line to the device. */
  360.     for ( dy = 0; dy < ih; dy++ )
  361.         (*copy_mono)(dev, line, 0, line_size, gx_no_bitmap_id,
  362.             ix, iy + dy, line_width, 1, zero, one);
  363.  
  364.     return_check_interrupt(1);
  365. }
  366.  
  367. /* Rendering procedure for the general case of displaying a */
  368. /* monochrome image, dealing with multiple bit-per-sample images, */
  369. /* general transformations, and arbitrary single-component */
  370. /* color spaces (DeviceGray, CIEBasedA, Separation, Indexed). */
  371. /* This procedure handles a single scan line. */
  372. int
  373. image_render_mono(gs_image_enum *penum, byte *buffer, uint w, int h)
  374. {    gs_state *pgs = penum->pgs;
  375.     const int masked = penum->masked;
  376.     const fixed dxx = penum->fxx;
  377.     const fixed dxx3 = (dxx << 1) + dxx;
  378.     fixed xt = penum->xcur;
  379.     gs_color_space *pcs = pgs->color_space;
  380.     cs_proc_remap_color((*remap_color)) = pcs->type->remap_color;
  381.     gs_client_color cc;
  382.     cmap_proc_gray((*map_gray)) = pgs->cmap_procs->map_gray;
  383.     gx_device_color *pdevc = pgs->dev_color;
  384.     /* Make sure the cache setup matches the graphics state. */
  385.     /* Also determine whether all tiles fit in the cache. */
  386.     int tiles_fit = gx_check_tile_cache(pgs);
  387. #define image_set_gray(sample_value)\
  388.    { pdevc = &penum->dev_colors[sample_value];\
  389.      if ( pdevc->type == &gx_dc_none )\
  390.       {  if ( penum->device_color )\
  391.         (*map_gray)(byte2frac(sample_value), pdevc, pgs);\
  392.      else\
  393.       { decode_sample(sample_value, cc, 0);\
  394.         (*remap_color)(&cc, pcs, pdevc, pgs);\
  395.       }\
  396.       }\
  397.      else if ( pdevc->type != &gx_dc_pure )\
  398.       { if ( !tiles_fit )\
  399.          { code = gx_color_load(pdevc, pgs);\
  400.        if ( code < 0 ) return code;\
  401.      }\
  402.       }\
  403.    }
  404.     fixed xl = xt;
  405.     register const byte *psrc = buffer;
  406.     byte *endp = buffer + w;
  407.     fixed xrun = xt;        /* x at start of run */
  408.     register byte run = *psrc;    /* run value */
  409.     int htrun =            /* halftone run value */
  410.       (masked ? 255 : -2);
  411.     int code;
  412.  
  413.     *endp = ~endp[-1];    /* force end of run */
  414.     if ( penum->slow_loop )
  415.       { /* Skewed, or imagemask with a halftone. */
  416.         const fixed
  417.           dxy = penum->fxy, dyx = penum->fyx,
  418.           dyy = penum->fyy;
  419.         const fixed dxy3 = (dxy << 1) + dxy;
  420.         fixed ytf = penum->ycur;
  421.         fixed yrun = ytf;
  422.         for ( ; ; )
  423.           {    /* Skip large constant regions quickly, */
  424.         /* but don't slow down transitions too much. */
  425. sks:        if ( psrc[0] == run )
  426.           { if ( psrc[1] == run )
  427.               { if ( psrc[2] == run )
  428.               { if ( psrc[3] == run )
  429.                   { psrc += 4, xl += dxx << 2, ytf += dxy << 2;
  430.                 goto sks;
  431.                   }
  432.                 else
  433.                   psrc += 4, xl += dxx3, ytf += dxy3;
  434.               }
  435.                 else
  436.               psrc += 3, xl += dxx << 1, ytf += dxy << 1;
  437.               }
  438.             else
  439.               psrc += 2, xl += dxx, ytf += dxy;
  440.           }
  441.         else
  442.           psrc++;
  443.         /* Now fill the region between xrun and xl. */
  444.         if ( run != htrun )
  445.           { if ( run == 0 )
  446.               { if ( masked ) goto trans;
  447.               }
  448.             htrun = run;
  449.             image_set_gray(run);
  450.           }
  451.         code = gz_fill_pgram_fixed(xrun, yrun, xl - xrun,
  452.                        ytf - yrun, dyx, dyy,
  453.                        pdevc, pgs);
  454.         if ( code < 0 ) return code;
  455. trans:        if ( psrc > endp ) break;
  456.         yrun = ytf;
  457.         xrun = xl;
  458.         run = psrc[-1];
  459.         xl += dxx;
  460.         ytf += dxy;        /* harmless if no skew */
  461.           }
  462.       }
  463.     else            /* fast loop */
  464.       { /* No skew, and not imagemask with a halftone. */
  465.         const fixed adjust = penum->adjust;
  466.         fixed xa = (dxx >= 0 ? adjust : -adjust);
  467.         const int yt = penum->yci, iht = penum->hci;
  468.         gx_device *dev = gs_currentdevice(pgs);
  469.         dev_proc_fill_rectangle((*fill_proc)) = dev_proc(dev, fill_rectangle);
  470.         dev_proc_tile_rectangle((*tile_proc)) = dev_proc(dev, tile_rectangle);
  471.         dev_proc_copy_mono((*copy_mono_proc)) = dev_proc(dev, copy_mono);
  472.         /* If each pixel is likely to fit in a single halftone tile, */
  473.         /* determine that now (tile_offset = offset of row within tile). */
  474.         int tile_offset =
  475.           gx_check_tile_size(pgs,
  476.                  fixed2int_rounded(any_abs(dxx) + (xa << 1)),
  477.                  yt, iht);
  478.         gx_ht_order *porder = &pgs->dev_ht->order;
  479.         /* Fold the adjustment into xrun and xl, */
  480.         /* including the +0.5 for rounding. */
  481.         xrun = xrun - xa + fixed_half;
  482.         xl = xl + xa + fixed_half;
  483.         xa <<= 1;
  484.         for ( ; ; )
  485.           {    /* Skip large constant regions quickly, */
  486.         /* but don't slow down transitions too much. */
  487. skf:        if ( psrc[0] == run )
  488.           { if ( psrc[1] == run )
  489.               { if ( psrc[2] == run )
  490.               { if ( psrc[3] == run )
  491.                   { psrc += 4, xl += dxx << 2;
  492.                 goto skf;
  493.                   }
  494.                 else
  495.                   psrc += 4, xl += dxx3;
  496.               }
  497.                 else
  498.               psrc += 3, xl += dxx << 1;
  499.               }
  500.             else
  501.               psrc += 2, xl += dxx;
  502.           }
  503.         else
  504.           psrc++;
  505.         { /* Now fill the region between xrun and xl. */
  506.           int xi = fixed2int_var(xrun);
  507.           int wi = fixed2int_var(xl) - xi;
  508.           int tsx;
  509.           const gx_tile_bitmap *tile;
  510.           if ( wi <= 0 )
  511.             { if ( wi == 0 ) goto mt;
  512.               xi += wi, wi = -wi;
  513.             }
  514.           switch ( run )
  515.             {
  516.             case 0:
  517.               if ( masked ) goto mt;
  518.               if ( !color_is_pure(&penum->icolor0) ) goto ht;
  519.               code = (*fill_proc)(dev, xi, yt, wi, iht,
  520.                       penum->icolor0.colors.pure);
  521.               break;
  522.             case 255:        /* just for speed */
  523.               if ( !color_is_pure(&penum->icolor1) ) goto ht;
  524.               code = (*fill_proc)(dev, xi, yt, wi, iht,
  525.                       penum->icolor1.colors.pure);
  526.               break;
  527.             default:
  528. ht:              /* Use halftone if needed */
  529.               if ( run != htrun )
  530.             { image_set_gray(run);
  531.               htrun = run;
  532.             }
  533.               /* We open-code gx_fill_rectangle, */
  534.               /* because we've done some of the work for */
  535.               /* halftone tiles in advance. */
  536.               if ( color_is_pure(pdevc) )
  537.             { code = (*fill_proc)(dev, xi, yt, wi, iht,
  538.                           pdevc->colors.pure);
  539.             }
  540.               else if ( pdevc->type != &gx_dc_ht_binary )
  541.             { code = gx_fill_rectangle(xi, yt, wi, iht,
  542.                            pdevc, pgs);
  543.             }
  544.               else if ( tile_offset >= 0 &&
  545.                     (tile = pdevc->colors.binary.b_tile,
  546.                  (tsx = (xi + porder->phase.x) % tile->rep_width) + wi <= tile->size.x)
  547.                   )
  548.             { /* The pixel(s) fit(s) in a single (binary) tile. */
  549.               byte *row = tile->data + tile_offset;
  550.               code = (*copy_mono_proc)
  551.                 (dev, row, tsx, tile->raster, gx_no_bitmap_id,
  552.                  xi, yt, wi, iht,
  553.                  pdevc->colors.binary.color[0],
  554.                  pdevc->colors.binary.color[1]);
  555.             }
  556.               else
  557.             { code = (*tile_proc)(dev,
  558.                           pdevc->colors.binary.b_tile,
  559.                           xi, yt, wi, iht,
  560.                           pdevc->colors.binary.color[0],
  561.                           pdevc->colors.binary.color[1],
  562.                           porder->phase.x, porder->phase.y);
  563.             }
  564.             }
  565.             if ( code < 0 ) return code;
  566. mt:            if ( psrc > endp ) break;
  567.             xrun = xl - xa;    /* original xa << 1 */
  568.             run = psrc[-1];
  569.         }
  570.         xl += dxx;
  571.           }
  572.       }
  573.     return 1;
  574. }
  575.