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

  1. /* Copyright (C) 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. /* gxcht.c */
  20. /* Color halftone rendering for Ghostscript imaging library */
  21. #include "gx.h"
  22. #include "gserrors.h"
  23. #include "gxfixed.h"
  24. #include "gxmatrix.h"
  25. #include "gxdevice.h"
  26. #include "gxcmap.h"
  27. #include "gzstate.h"
  28. #include "gzht.h"
  29.  
  30. /* Imported procedures */
  31. extern gx_tile_bitmap *gx_render_ht(P2(gx_ht_cache *, int));
  32.  
  33. /*** Big memory machines ***/
  34. #define tile_longs_LARGE 256
  35. /*** Small memory machines ***/
  36. #define tile_longs_SMALL 64
  37.  
  38. #if arch_ints_are_short
  39. #  define tile_longs tile_longs_SMALL
  40. #else
  41. #  define tile_longs tile_longs_LARGE
  42. #endif
  43.  
  44. /* Forward references. */
  45. private void set_ht_colors(P6(gx_color_index [16], gx_tile_bitmap *[4],
  46.   const gx_device_color *, gx_device *, gx_ht_cache *[4], int));
  47. private void set_color_ht(P9(gx_tile_bitmap *, int, int, int, int, int, int,
  48.   const gx_color_index [16], const gx_tile_bitmap *[4]));
  49.  
  50. /* Define a table for expanding 8x1 bits to 8x4. */
  51. private const bits32 far_data expand_8x1_to_8x4[256] = {
  52. #define x16(c)\
  53.   c+0, c+1, c+0x10, c+0x11, c+0x100, c+0x101, c+0x110, c+0x111,\
  54.   c+0x1000, c+0x1001, c+0x1010, c+0x1011, c+0x1100, c+0x1101, c+0x1110, c+0x1111
  55.     x16(0x00000000), x16(0x00010000), x16(0x00100000), x16(0x00110000),
  56.     x16(0x01000000), x16(0x01010000), x16(0x01100000), x16(0x01110000),
  57.     x16(0x10000000), x16(0x10010000), x16(0x10100000), x16(0x10110000),
  58.     x16(0x11000000), x16(0x11010000), x16(0x11100000), x16(0x11110000)
  59. #undef x16
  60. };
  61.  
  62. /* Prepare to use a colored halftone, by loading the default cache. */
  63. int
  64. gx_dc_ht_colored_load(gx_device_color *pdevc, const gs_state *pgs)
  65. {    const gx_ht_order *porder = &pgs->dev_ht->components[0].corder;
  66.     gx_ht_cache *pcache = pgs->ht_cache;
  67.     if ( pcache->order.bits != porder->bits )
  68.         gx_ht_init_cache(pcache, porder);
  69.     return 0;
  70. }
  71.  
  72. /* Fill a rectangle with a colored halftone. */
  73. int
  74. gx_dc_ht_colored_fill_rectangle(const gx_device_color *pdevc, int x, int y,
  75.   int w, int h, gx_device *dev, const gs_state *pgs)
  76. {    ulong tbits[tile_longs];
  77. #define tile_bytes (tile_longs * size_of(long))
  78.     gx_tile_bitmap tile;
  79.     gx_device_halftone *pdht = pgs->dev_ht;
  80.     int depth = dev->color_info.depth;
  81.     int nplanes = dev->color_info.num_components;
  82.     gx_color_index colors[16];    
  83.     gx_tile_bitmap *bits[4];
  84.     gx_ht_cache *caches[4];
  85.     int code = 0;
  86.     int raster;
  87.     uint size_x;
  88.     int dw, dh;
  89.     if ( w <= 0 || h <= 0 )
  90.         return 0;
  91.     tile.data = (byte *)tbits;
  92.     tile.id = gx_no_bitmap_id;
  93.     if ( pdht->components == 0 )
  94.         caches[0] = caches[1] = caches[2] = caches[3] = pgs->ht_cache;
  95.     else
  96.     {    gx_ht_order_component *pocs = pdht->components;
  97.         pocs[0].corder.cache = pgs->ht_cache;    /* Default */
  98.         caches[0] = pocs[pdht->color_indices[0]].corder.cache;
  99.         caches[1] = pocs[pdht->color_indices[1]].corder.cache;
  100.         caches[2] = pocs[pdht->color_indices[2]].corder.cache;
  101.         caches[3] = pocs[pdht->color_indices[3]].corder.cache;
  102.     }
  103.     set_ht_colors(colors, bits, pdevc, dev, caches, nplanes);
  104.     size_x = w * depth;
  105.     raster = bitmap_raster(size_x);
  106.     if ( raster > tile_bytes )
  107.     {    /* We can't even do an entire line at once. */
  108.         dw = tile_bytes * 8 / depth;
  109.         size_x = dw * depth;
  110.         raster = bitmap_raster(size_x);
  111.         dh = 1;
  112.     }
  113.     else
  114.     {    /* Do as many lines as will fit. */
  115.         dw = w;
  116.         dh = tile_bytes / raster;
  117.         if ( dh > h ) dh = h;
  118.     }
  119.     /* Now the tile will definitely fit. */
  120.     tile.raster = raster;
  121.     tile.rep_width = tile.size.x = size_x;
  122.     while ( w )
  123.     {    int cy = y, ch = dh, left = h;
  124.         tile.rep_height = tile.size.y = ch;
  125.         for ( ; ; )
  126.         {    /* The cast in the following statement is bogus, */
  127.             /* but some compilers won't accept an array type, */
  128.             /* and won't accept it without a cast. */
  129.             set_color_ht(&tile, x, cy, dw, ch,
  130.                      depth, nplanes, colors,
  131.                      (const gx_tile_bitmap **)bits);
  132.             code = (*dev_proc(dev, copy_color))(dev,
  133.                     tile.data, 0, raster,
  134.                     gx_no_bitmap_id, x, cy, dw, ch);
  135.             if ( code < 0 )
  136.                 return code;
  137.             if ( !(left -= ch) )
  138.                 break;
  139.             cy += ch;
  140.             if ( ch > left )
  141.                 tile.rep_height = tile.size.y = ch = left;
  142.         }
  143.         if ( !(w -= dw) )
  144.             break;
  145.         x += dw;
  146.         if ( dw > w)
  147.             dw = w, tile.rep_width = tile.size.x = size_x;
  148.     }
  149.     return code;
  150. }
  151.  
  152. /*
  153.  * We construct color halftone tiles out of 3 or 4 "planes".
  154.  * Each plane specifies halftoning for one component (R/G/B or C/M/Y/K).
  155.  */
  156.  
  157. /* Set up the colors and the individual plane halftone bitmaps. */
  158. private void
  159. set_ht_colors(gx_color_index colors[16], gx_tile_bitmap *bits[4],
  160.   const gx_device_color *pdc, gx_device *dev, gx_ht_cache *caches[4],
  161.   int nplanes)
  162. {    gx_color_value v0[4], v1[4];
  163.     static const ulong no_bitmap_data[] =
  164.      { 0, 0, 0, 0, 0, 0, 0, 0 };
  165.     static gx_tile_bitmap no_bitmap =
  166.      { 0, sizeof(ulong), { sizeof(ulong) * 8, countof(no_bitmap_data) },
  167.        gx_no_bitmap_id, 1, 1
  168.      };
  169.     gx_color_value max_rgb = dev->color_info.dither_rgb - 1;
  170.     no_bitmap.data = (byte *)no_bitmap_data;
  171. #define cb(i) pdc->colors.colored.c_base[i]
  172. #define cl(i) pdc->colors.colored.c_level[i]
  173. #define set_plane_color(i)\
  174. {    uint q = cb(i);\
  175.     uint r = cl(i);\
  176.     v0[i] = fractional_color(q, max_rgb);\
  177.     if ( r == 0 )\
  178.         v1[i] = v0[i], bits[i] = &no_bitmap;\
  179.     else\
  180.         v1[i] = fractional_color(q+1, max_rgb),\
  181.         bits[i] = gx_render_ht(caches[i], r);\
  182. }
  183. #define map8(m)\
  184.   m(0, v0[0], v0[1], v0[2]); m(1, v1[0], v0[1], v0[2]);\
  185.   m(2, v0[0], v1[1], v0[2]); m(3, v1[0], v1[1], v0[2]);\
  186.   m(4, v0[0], v0[1], v1[2]); m(5, v1[0], v0[1], v1[2]);\
  187.   m(6, v0[0], v1[1], v1[2]); m(7, v1[0], v1[1], v1[2])
  188.     set_plane_color(0);
  189.     set_plane_color(1);
  190.     set_plane_color(2);
  191.     if ( nplanes == 3 )
  192.     {    gx_color_value alpha = pdc->colors.colored.alpha;
  193.         if ( alpha == gx_max_color_value )
  194.         {    
  195. #ifdef DEBUG
  196. #  define map1(r, g, b) gx_map_rgb_color(dev, r, g, b)
  197. #else
  198.             dev_proc_map_rgb_color((*map)) =
  199.                 dev_proc(dev, map_rgb_color);
  200. #  define map1(r, g, b) (*map)(dev, r, g, b)
  201. #endif
  202. #define mapc(i, r, g, b)\
  203.   colors[i] = map1(r, g, b)
  204.             map8(mapc);
  205. #undef map1
  206. #undef mapc
  207.         }
  208.         else
  209.         {
  210. #ifdef DEBUG
  211. #  define map1(r, g, b) gx_map_rgb_alpha_color(dev, r, g, b, alpha)
  212. #else
  213.             dev_proc_map_rgb_alpha_color((*map)) =
  214.                 dev_proc(dev, map_rgb_alpha_color);
  215. #  define map1(r, g, b) (*map)(dev, r, g, b, alpha)
  216. #endif
  217. #define mapc(i, r, g, b)\
  218.   colors[i] = map1(r, g, b)
  219.             map8(mapc);
  220. #undef map1
  221. #undef mapc
  222.         }
  223.     }
  224.     else
  225.     {
  226. #ifdef DEBUG
  227. #  define map1(r, g, b, w) gx_map_cmyk_color(dev, r, g, b, w)
  228. #else
  229.         dev_proc_map_cmyk_color((*map)) =
  230.             dev_proc(dev, map_cmyk_color);
  231. #  define map1(r, g, b, w) (*map)(dev, r, g, b, w)
  232. #endif
  233.         set_plane_color(3);
  234. #define mapc(i, r, g, b)\
  235.   colors[i] = map1(r, g, b, v0[3]);\
  236.   colors[i+8] = map1(r, g, b, v1[3])
  237.         map8(mapc);
  238. #undef map1
  239. #undef mapc
  240.         }
  241. #undef map8
  242. #undef set_plane_color
  243. #undef cb
  244. #undef cl
  245. }
  246.  
  247. /* Render the combined halftone. */
  248. private void
  249. set_color_ht(
  250.     gx_tile_bitmap *ctile,    /* the output tile; data, raster, size are set */
  251.     int px,            /* the initial phase of the output tile */
  252.     int py,
  253.     int w,            /* how much of the tile to set */
  254.     int h,
  255.     int depth,        /* depth of tile (4, 8, 16, 24, 32) */
  256.     int nplanes,        /* # of source planes, 3 or 4 */
  257.     const gx_color_index colors[16], /* the actual colors for the tile, */
  258.                 /* actually [1 << nplanes] */
  259.     const gx_tile_bitmap *bits[4]    /* the bitmaps for the planes, */
  260.                 /* actually [nplanes] */
  261. )
  262. {    /* Note that the planes are specified in the order RGB or CMYK, but */
  263.     /* the indices used for the internal colors array are BGR or KYMC. */
  264.  
  265.     int x, y;
  266.     struct tile_cursor_s {
  267.         int xoffset;
  268.         int xshift;
  269.         uint xbytes;
  270.         int xbits;
  271.         const byte *row;
  272.         const byte *tdata;
  273.         uint raster;
  274.         const byte *data;
  275.         uint shift;
  276.     } cursor[4];
  277.     int dbytes = depth >> 3;
  278.     uint dest_raster = ctile->raster;
  279.     byte *dest_row =
  280.       ctile->data + dest_raster * (h - 1) + (w * depth) / 8;
  281.     int endx = w + px;
  282.  
  283.     if_debug6('h',
  284.           "[h]color_ht: x=%d y=%d w=%d h=%d nplanes=%d depth=%d\n",
  285.           px, py, w, h, nplanes, depth);
  286.  
  287.     /* Do one-time cursor initialization. */
  288.     {    int lasty = h - 1 + py;
  289. #define set_start(i, c, btile)\
  290. { int tw = btile->size.x;\
  291.   int bx = endx % tw;\
  292.   int by = lasty % btile->size.y;\
  293.   c.xoffset = bx >> 3;\
  294.   c.xshift = 8 - (bx & 7);\
  295.   c.xbytes = (tw - 1) >> 3;\
  296.   c.xbits = ((tw - 1) & 7) + 1;\
  297.   c.tdata = btile->data;\
  298.   c.raster = btile->raster;\
  299.   c.row = c.tdata + by * c.raster;\
  300.   if_debug5('h', "[h]plane %d: size=%d,%d bx=%d by=%d\n",\
  301.         i, tw, btile->size.y, bx, by);\
  302. }
  303.         set_start(0, cursor[0], bits[0]);
  304.         set_start(1, cursor[1], bits[1]);
  305.         set_start(2, cursor[2], bits[2]);
  306.         if ( nplanes == 4 )
  307.             set_start(3, cursor[3], bits[3]);
  308. #undef set_start
  309.     }
  310.  
  311.     /* Now compute the actual tile. */
  312.     for ( y = h; ; dest_row -= dest_raster )
  313.     {    byte *dest = dest_row;
  314. #define set_row(c)\
  315.   {    c.data = c.row + c.xoffset;\
  316.     c.shift = c.xshift;\
  317.   }
  318.         set_row(cursor[0]);
  319.         set_row(cursor[1]);
  320.         set_row(cursor[2]);
  321.         if ( nplanes == 4 )
  322.         {    set_row(cursor[3]);
  323.         }
  324. #undef set_row
  325.         --y;
  326.         for ( x = w; x > 0; )
  327.         {    bits32 indices;
  328.             int nx, i;
  329.             register uint bits;
  330. /* Get the next byte's worth of bits.  Note that there may be */
  331. /* excess bits set beyond the 8th. */
  332. #define next_bits(c)\
  333. {    if ( c.data > c.row )\
  334.     {    bits = ((c.data[-1] << 8) | *c.data) >> c.shift;\
  335.         c.data--;\
  336.     }\
  337.     else\
  338.     {    bits = *c.data >> c.shift;\
  339.         c.data += c.xbytes;\
  340.         if ( (c.shift += c.xbits) < 8 )\
  341.         {    bits |= *c.data << (8 - c.shift);\
  342.         }\
  343.         else\
  344.         {    c.shift -= 8;\
  345.             bits |= ((c.data[-1] << 8) | *c.data) >> c.shift;\
  346.             c.data--;\
  347.         }\
  348.     }\
  349. }
  350.             if ( nplanes == 4 )
  351.             {    next_bits(cursor[3]);
  352.                 indices = expand_8x1_to_8x4[bits & 0xff] << 1;
  353.             }
  354.             else
  355.                 indices = 0;
  356.             next_bits(cursor[2]);
  357.             indices = (indices | expand_8x1_to_8x4[bits & 0xff]) << 1;
  358.             next_bits(cursor[1]);
  359.             indices = (indices | expand_8x1_to_8x4[bits & 0xff]) << 1;
  360.             next_bits(cursor[0]);
  361.             indices |= expand_8x1_to_8x4[bits & 0xff];
  362. #undef next_bits
  363.             nx = min(x, 8);
  364.             x -= nx;
  365.             switch ( dbytes )
  366.             {
  367.             case 0:            /* 4 */
  368.                 for ( i = nx; --i >= 0; indices >>= 4 )
  369.               {    byte tcolor =
  370.                     (byte)colors[(uint)indices & 0xf];
  371.                 if ( (x + i) & 1 )
  372.                     *--dest = tcolor;
  373.                 else
  374.                     *dest = (*dest & 0xf) + (tcolor << 4);
  375.               }
  376.                 break;
  377.             case 4:            /* 32 */
  378.                 for ( i = nx; --i >= 0; indices >>= 4 )
  379.               {    gx_color_index tcolor =
  380.                     colors[(uint)indices & 0xf];
  381.                 dest -= 4;
  382.                 dest[3] = (byte)tcolor;
  383.                 dest[2] = (byte)(tcolor >> 8);
  384.                 tcolor >>= 16;
  385.                 dest[1] = (byte)tcolor;
  386.                 dest[0] = (byte)((uint)tcolor >> 8);
  387.               }
  388.                 break;
  389.             case 3:            /* 24 */
  390.                 for ( i = nx; --i >= 0; indices >>= 4 )
  391.               {    gx_color_index tcolor =
  392.                     colors[(uint)indices & 0xf];
  393.                 dest -= 3;
  394.                 dest[2] = (byte)tcolor;
  395.                 dest[1] = (byte)((uint)tcolor >> 8);
  396.                 tcolor >>= 16;
  397.                 dest[0] = (byte)((uint)tcolor >> 8);
  398.               }
  399.                 break;
  400.             case 2:            /* 16 */
  401.                 for ( i = nx; --i >= 0; indices >>= 4 )
  402.               {    uint tcolor =
  403.                     (uint)colors[(uint)indices & 0xf];
  404.                 dest -= 2;
  405.                 dest[1] = (byte)tcolor;
  406.                 dest[0] = (byte)(tcolor >> 8);
  407.               }
  408.                 break;
  409.             case 1:            /* 8 */
  410.                 for ( i = nx; --i >= 0; indices >>= 4 )
  411.                     *--dest = (byte)colors[(uint)indices & 0xf];
  412.                 break;
  413.             }
  414.         }
  415.         if ( y == 0 )
  416.             break;
  417. #define step_row(c, i)\
  418.   if ( c.row > c.tdata )\
  419.     c.row -= c.raster;\
  420.   else\
  421.     c.row += c.raster * (bits[i]->size.y - 1)
  422.         step_row(cursor[0], 0);
  423.         step_row(cursor[1], 1);
  424.         step_row(cursor[2], 2);
  425.         if ( nplanes == 4)
  426.             step_row(cursor[3], 3);
  427. #undef step_row
  428.     }
  429. }
  430.