dither.c
上传用户:zlh9724
上传日期:2007-01-04
资源大小:1991k
文件大小:26k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /*    dither.c 
  2.     - Dave Raggett, 16th December 1994
  3.             - revised 9th Feb 1994 to speed decoding & add gif89 support
  4.     - separated from gif.c by Phill Hallam-Baker
  5.    The colors are preallocated by image.c with 4:8:4 R:G:B colors and
  6.    16 grey scales. These are rendered using an ordered dither based on
  7.    16x16 dither matrices for monochrome, greyscale and color images.
  8.    This approach ensures that we won't run out of colors regardless of
  9.    how many images are on screen or how many independent copies of www
  10.    are running at any time. The scheme is compatible with HP's MPOWER
  11.    tools. The code will be extended to take advantage of 24 bit direct
  12.    color or secondary true color hardware colormaps as soon as practical.
  13. */
  14. #include <X11/Intrinsic.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include "www.h"
  18. #include "image.h"
  19. #define MAXCOLORMAPSIZE 256
  20. #define TRUE    1
  21. #define FALSE   0
  22. #define CM_RED          0
  23. #define CM_GREEN        1
  24. #define CM_BLUE         2
  25. #define INTERLACE       0x40
  26. #define LOCALCOLORMAP   0x80
  27. #define BitSet(byte, bit) (((byte) & (bit)) == (bit))
  28. #define LM_to_uint(a,b)   (((b)<<8)|(a))
  29. extern Display *display;
  30. extern int screen;
  31. extern int RPixelShift;
  32. extern int depth;
  33. extern Colormap colormap;
  34. extern int imaging;  /* set to COLOR888, COLOR232, GREY4 or MONO */
  35. extern int tileWidth, tileHeight;
  36. extern unsigned char *tileData;
  37. extern unsigned long windowColor;
  38. extern unsigned long greymap[16];
  39. extern debug; /* howcome 16/10/94 */
  40. extern unsigned long transparent; /* howcome 30/10/94 */
  41. extern BOOL Quiet; /* howcome 11/8/95 */
  42. extern unsigned char* gamma_table;
  43. extern unsigned long stdcmap[128];  /* 2/3/2 color maps for gifs etc */
  44. unsigned long mycmap[256];
  45. /* mycmap is an array containing X11 pixel values. The layout of the array is as follows:
  46.     mycmap[0] = BlackPixel(display, screen);
  47.     mycmap[127] = WhitePixel(display, screen);
  48.     mycmap[1-126]: magic colors
  49.     mycymap[128] = BlackPixel(display, screen);
  50.     mycmap[143] = WhitePixel(display, screen);
  51.     mycmap[129-142]: magic gray
  52.     150-159: read only colors for application
  53.     160-199: read only colors for current document
  54.     200-209: read/write colors for application
  55.     210-249: read/write colors for current document
  56.     
  57. */
  58. #define RO_COL_DOC_START 160
  59. #define RO_COL_DOC_END   199
  60. #define RW_COL_DOC_START 210
  61. #define RW_COL_DOC_END   249
  62. int Magic256[256] =    /* for halftoning */
  63. {
  64.     0, 223, 48, 207, 14, 237, 62, 221, 3, 226, 51, 210, 13, 236, 61, 220,
  65.     175, 80, 128, 96, 189, 94, 141, 110, 178, 83, 130, 99, 188, 93, 140, 109,
  66.     191, 32, 239, 16, 205, 46, 253, 30, 194, 35, 242, 19, 204, 45, 252, 29,
  67.     112, 143, 64, 159, 126, 157, 78, 173, 115, 146, 67, 162, 125, 156, 77, 172,
  68.     11, 234, 59, 218, 5, 228, 53, 212, 8, 231, 56, 215, 6, 229, 54, 213,
  69.     186, 91, 138, 107, 180, 85, 132, 101, 183, 88, 135, 104, 181, 86, 133, 102,
  70.     202, 43, 250, 27, 196, 37, 244, 21, 199, 40, 247, 24, 197, 38, 245, 22,
  71.     123, 154, 75, 170, 117, 148, 69, 164, 120, 151, 72, 167, 118, 149, 70, 165,
  72.     12, 235, 60, 219, 2, 225, 50, 209, 15, 238, 63, 222, 1, 224, 49, 208,
  73.     187, 92, 139, 108, 177, 82, 129, 98, 190, 95, 142, 111, 176, 81, 128, 97,
  74.     203, 44, 251, 28, 193, 34, 241, 18, 206, 47, 254, 31, 192, 33, 240, 17,
  75.     124, 155, 76, 171, 114, 145, 66, 161, 127, 158, 79, 174, 113, 144, 65, 160,
  76.     7, 230, 55, 214, 9, 232, 57, 216, 4, 227, 52, 211, 10, 233, 58, 217,
  77.     182, 87, 134, 103, 184, 89, 136, 105, 179, 84, 131, 100, 185, 90, 137, 106,
  78.     198, 39, 246, 23, 200, 41, 248, 25, 195, 36, 243, 20, 201, 42, 249, 26,
  79.     119, 150, 71, 166, 121, 152, 73, 168, 116, 147, 68, 163, 122, 153, 74, 169
  80. };
  81. int Magic16[256] =    /* for 16 levels of gray */
  82. {
  83.     0, 13, 3, 12, 1, 14, 4, 13, 0, 13, 3, 12, 1, 14, 4, 13,
  84.     10, 5, 8, 6, 11, 6, 8, 6, 10, 5, 8, 6, 11, 5, 8, 6,
  85.     11, 2, 14, 1, 12, 3, 15, 2, 11, 2, 14, 1, 12, 3, 15, 2,
  86.     7, 8, 4, 9, 7, 9, 5, 10, 7, 9, 4, 10, 7, 9, 5, 10,
  87.     1, 14, 3, 13, 0, 13, 3, 12, 0, 14, 3, 13, 0, 13, 3, 13,
  88.     11, 5, 8, 6, 11, 5, 8, 6, 11, 5, 8, 6, 11, 5, 8, 6,
  89.     12, 3, 15, 2, 12, 2, 14, 1, 12, 2, 15, 1, 12, 2, 14, 1,
  90.     7, 9, 4, 10, 7, 9, 4, 10, 7, 9, 4, 10, 7, 9, 4, 10,
  91.     1, 14, 4, 13, 0, 13, 3, 12, 1, 14, 4, 13, 0, 13, 3, 12,
  92.     11, 5, 8, 6, 10, 5, 8, 6, 11, 6, 8, 7, 10, 5, 8, 6,
  93.     12, 3, 15, 2, 11, 2, 14, 1, 12, 3, 15, 2, 11, 2, 14, 1,
  94.     7, 9, 4, 10, 7, 9, 4, 9, 7, 9, 5, 10, 7, 8, 4, 9,
  95.     0, 14, 3, 13, 1, 14, 3, 13, 0, 13, 3, 12, 1, 14, 3, 13,
  96.     11, 5, 8, 6, 11, 5, 8, 6, 11, 5, 8, 6, 11, 5, 8, 6,
  97.     12, 2, 14, 1, 12, 2, 15, 1, 11, 2, 14, 1, 12, 2, 15, 2,
  98.     7, 9, 4, 10, 7, 9, 4, 10, 7, 9, 4, 10, 7, 9, 4, 10
  99. };
  100. int Magic32[256] =    /* for 8 levels of green */
  101. {
  102.     0, 27, 6, 25, 2, 29, 8, 27, 0, 27, 6, 26, 2, 29, 7, 27,
  103.     21, 10, 16, 12, 23, 11, 17, 13, 22, 10, 16, 12, 23, 11, 17, 13,
  104.     23, 4, 29, 2, 25, 6, 31, 4, 24, 4, 29, 2, 25, 5, 31, 4,
  105.     14, 17, 8, 19, 15, 19, 9, 21, 14, 18, 8, 20, 15, 19, 9, 21,
  106.     1, 28, 7, 27, 1, 28, 6, 26, 1, 28, 7, 26, 1, 28, 7, 26,
  107.     23, 11, 17, 13, 22, 10, 16, 12, 22, 11, 16, 13, 22, 10, 16, 12,
  108.     25, 5, 30, 3, 24, 4, 30, 3, 24, 5, 30, 3, 24, 5, 30, 3,
  109.     15, 19, 9, 21, 14, 18, 8, 20, 15, 18, 9, 20, 14, 18, 8, 20,
  110.     1, 29, 7, 27, 0, 27, 6, 25, 2, 29, 8, 27, 0, 27, 6, 25,
  111.     23, 11, 17, 13, 22, 10, 16, 12, 23, 12, 17, 13, 21, 10, 16, 12,
  112.     25, 5, 31, 3, 23, 4, 29, 2, 25, 6, 31, 4, 23, 4, 29, 2,
  113.     15, 19, 9, 21, 14, 18, 8, 20, 15, 19, 10, 21, 14, 18, 8, 19,
  114.     1, 28, 7, 26, 1, 28, 7, 26, 0, 28, 6, 26, 1, 28, 7, 26,
  115.     22, 11, 16, 12, 22, 11, 17, 13, 22, 10, 16, 12, 23, 11, 17, 13,
  116.     24, 5, 30, 3, 24, 5, 30, 3, 24, 4, 30, 2, 24, 5, 30, 3,
  117.     14, 18, 9, 20, 15, 19, 9, 20, 14, 18, 8, 20, 15, 19, 9, 21
  118. };
  119. int Magic64[256] =    /* for 4 levels of red and blue */
  120. {
  121.     0, 55, 12, 51, 3, 59, 15, 55, 1, 56, 13, 52, 3, 58, 15, 54,
  122.     43, 20, 32, 24, 47, 23, 35, 27, 44, 20, 32, 24, 47, 23, 35, 27,
  123.     47, 8, 59, 4, 51, 11, 63, 7, 48, 9, 60, 5, 50, 11, 62, 7,
  124.     28, 35, 16, 39, 31, 39, 19, 43, 28, 36, 16, 40, 31, 39, 19, 43,
  125.     3, 58, 15, 54, 1, 56, 13, 52, 2, 57, 14, 53, 1, 57, 13, 53,
  126.     46, 22, 34, 26, 45, 21, 33, 25, 45, 22, 33, 26, 45, 21, 33, 25,
  127.     50, 11, 62, 7, 48, 9, 60, 5, 49, 10, 61, 6, 49, 9, 61, 5,
  128.     30, 38, 18, 42, 29, 37, 17, 41, 30, 37, 18, 41, 29, 37, 17, 41,
  129.     3, 58, 15, 54, 0, 56, 12, 52, 4, 59, 16, 55, 0, 55, 12, 51,
  130.     46, 23, 34, 27, 44, 20, 32, 24, 47, 23, 35, 27, 44, 20, 32, 24,
  131.     50, 11, 62, 7, 48, 8, 60, 4, 51, 12, 63, 8, 47, 8, 59, 4,
  132.     31, 38, 19, 42, 28, 36, 16, 40, 31, 39, 19, 43, 28, 36, 16, 40,
  133.     2, 57, 14, 53, 2, 57, 14, 53, 1, 56, 13, 52, 2, 58, 14, 54,
  134.     45, 21, 33, 25, 46, 22, 34, 26, 44, 21, 32, 25, 46, 22, 34, 26,
  135.     49, 10, 61, 6, 49, 10, 61, 6, 48, 9, 60, 5, 50, 10, 62, 6,
  136.     29, 37, 17, 41, 30, 38, 18, 42, 29, 36, 17, 40, 30, 38, 18, 42
  137. };
  138. Byte color_ix_start = 128, color_ix_end = 128;
  139. unsigned long magic2color(Byte ix)
  140. {
  141.     int r, g, b;
  142.     unsigned long color;
  143.     
  144.     r = (ix << 6) & 0xC0;
  145.     g = (ix << 3) & 0xE0;
  146.     b = (ix << 1) & 0xC0;
  147.     GetColor(r, g, b, &color);
  148. /*    fprintf(stderr,"color %d %d %d ->  %ldn",r,g,b,color);*/
  149.     return color;
  150. }
  151. Byte rgb2magic(int r, int g, int b)
  152. {
  153.     /* janet 21/07/95: not used:    int cr, cg, cb; */
  154.     if (r == g && g == b) {
  155. /*
  156. cr = Voltage2Brightness(r);
  157. return(128 | (cr >> 4));
  158. */
  159. return(128 | r >> 4);
  160.     }
  161. /*
  162.     cr = Voltage2Brightness(r);
  163.     cg = Voltage2Brightness(g);
  164.     cb = Voltage2Brightness(b);
  165.     
  166.     r = cr & 0xC0;
  167.     g = cg & 0xE0;
  168.     b = cb & 0xC0;
  169. */
  170.     return ((r >> 6) | (g >> 3) | (b >> 1));
  171. }
  172. long ix2color(int ix)
  173. {
  174.     return mycmap[ix];
  175. }
  176. Byte rgb2ix(int status, int r, int g, int b, Bool blink)
  177. {
  178.     XColor xc;
  179.     /* janet 21/07/95: not used:    int cr, cg, cb; */
  180.     unsigned long pixels[1];
  181.     int i;
  182.     unsigned long px;
  183.     if (status)
  184. return (255);
  185.     xc.red = r << 8;
  186.     xc.green = g << 8;
  187.     xc.blue = b << 8;
  188.     xc.flags = DoRed | DoGreen | DoBlue;
  189.     if (blink) {
  190. if (XAllocColorCells(display, colormap, False, NULL, 0, pixels, 1)) {
  191.     xc.pixel = pixels[0];
  192.     XStoreColor(display, colormap, &xc);
  193.     for(i = RW_COL_DOC_START; (i <= RW_COL_DOC_END) && (mycmap[i] != 0); i++)
  194. ;
  195.     mycmap[i] = xc.pixel;
  196.     return(i);
  197. }
  198.     }
  199.     if (!XAllocColor(display, colormap, &xc)) {
  200.         /* janet 21/07/95: not used: Byte ix; */
  201. /* janet 21/07/95: not used: unsigned long color; */
  202.     
  203. if (VERBOSE_TRACE)
  204.     fprintf(stderr,"Can't allocate exact color for #%2.2x%2.2x%2.2x, ", r, g, b);
  205. r = min(r, 255) & 0xC0;
  206. g = min(g, 255) & 0xE0;
  207. b = min(b, 255) & 0xC0;
  208. if (VERBOSE_TRACE)
  209.     fprintf(stderr,"using substitute #%2.2x%2.2x%2.2xn", r, g, b);
  210. /* fprintf(stderr,"rgb2ix: %dn", ((r >> 6) | (g >> 3) | (b >> 1)));*/
  211. return ((r >> 6) | (g >> 3) | (b >> 1));
  212.     }
  213.     px = xc.pixel;
  214.     for (i = 0; i < 144; i++) {
  215. if (mycmap[i] == px)
  216.     return(i);
  217.     }
  218.     for (i = RO_COL_DOC_START; (i <= RO_COL_DOC_END) && (mycmap[i] != 0); i++) {
  219. if (mycmap[i] == px) {
  220.     if (COLOR_TRACE)
  221. fprintf(stderr,"rgb2ix old: (%d %d %d) %d, %ldn",r,g,b,i,px);
  222.     return(i);
  223. }
  224.     }
  225.     if (i <= RO_COL_DOC_END) {
  226. mycmap[i] = px;
  227. if (COLOR_TRACE)
  228.     fprintf(stderr,"rgb2ix new: (%d %d %d) %d, %ldn",r, g, b, i,px);
  229. return (i);
  230.     }
  231.     fprintf(stderr,"rgb2ix ran out of colors.. n");
  232.     /* janet 21/07/95 function does not return value! */
  233.     /* return ???; */ 
  234. }
  235. long rgb2color(int status, int r, int g, int b, Bool rw)
  236. {
  237.     return(ix2color(rgb2ix(status, r, g, b, rw)));
  238. }
  239. void rgbClear()
  240. {
  241.     int i;
  242.     /* janet 21/07/95: not used:    XColor xca; */
  243.     if (COLOR_TRACE)
  244. fprintf(stderr,"rgbClearn");
  245.     for (i = RO_COL_DOC_START; (i <= RO_COL_DOC_END) && (mycmap[i] != 0); i++) {
  246. if (COLOR_TRACE)
  247.     fprintf(stderr,"rgbClear %d %ldn", i, mycmap[i]);
  248. XFreeColors( display, colormap, &mycmap[i], 1, 0L );
  249. mycmap[i]=0;
  250.     }
  251. }
  252. static int ImageOutputScanlines_1_2_4 (output_image_data *output, 
  253. image_data *idata) {
  254.   /*extern int ImageOutputScanlines_1_2_4 (output_image_data *output, 
  255. image_data *idata) { */
  256.     /*janet 21/07/95: not used:    unsigned char   c;      */
  257.     int             v;
  258.     int             xpos = 0, ypos = 0, yindex;   /* janet 21/07/95: not used: pass = 0 */
  259.     unsigned char   *dp, *scan_buffer;  /* janet 21/07/95: not used: *dy */
  260.     int             cr=0, cg=0, cb=0, r, g, b, row, col; /* 12-Mar-96 <herman@htbrug.hobby.nl> */
  261.     /*  janet 21/07/95: not used:   Color           color; */
  262.     int             ppb, bpl, shift=0;
  263.     int             newbyte;
  264. /* howcome added support for 1,2,4 depths */
  265.     if (depth != 1 && depth !=2 && depth !=4) {
  266. fprintf(stderr,"sorry, images are not supported for depth %dn",depth);
  267. return FALSE;
  268.     }
  269.     ppb = 8/depth; /* pixels per byte */
  270.     bpl = output->bytes_per_row;
  271.     newbyte = 1;
  272.     
  273.     if (TRUE) {
  274.         dp = output->data + output->row * output->bytes_per_row;
  275.         for (yindex = 0; yindex < idata->rows; yindex++) {
  276.     ypos = yindex + output->row;
  277.     scan_buffer = idata->buffer + (yindex * output->width * 3);
  278.             col = ypos & 15;
  279.             for (xpos = 0; xpos < idata->width; ++xpos) {
  280.                 row = xpos & 15;
  281. if (newbyte) {
  282.   *dp = 0;
  283.   newbyte = 0;
  284. }
  285.                 if (imaging == COLOR232) {
  286.     /* do we have to do grayscale like in ImageOutputScanlines_8 ?? */
  287.     switch (idata->components) {
  288.       case 1:
  289. cr = cg = cb = Voltage2Brightness(scan_buffer[xpos]);
  290. /* cr = cg = cb = gamma_table[scan_buffer[xpos]]; */
  291. break;
  292.       case 3:
  293. cr = Voltage2Brightness(scan_buffer [0+(xpos * 3)]);
  294. cg = Voltage2Brightness(scan_buffer [1+(xpos * 3)]);
  295. cb = Voltage2Brightness(scan_buffer [2+(xpos * 3)]);
  296. #if 0
  297. cr = gamma_table[scan_buffer [0+(xpos * 3)]];
  298. cg = gamma_table[scan_buffer [1+(xpos * 3)]];
  299. cb = gamma_table[scan_buffer [2+(xpos * 3)]];
  300. #endif
  301. break;
  302.       default:
  303. fprintf(stderr,"ImageOutputScanlines_1_2_4, components = %dn",idata->components);
  304.     }
  305.                     r = cr & 0xC0;
  306.                     g = cg & 0xE0;
  307.                     b = cb & 0xC0;
  308.                     v = (row << 4) + col;
  309.                     if (cr - r > Magic64[v])
  310.                         r += 64;
  311.                     if (cg - g > Magic32[v])
  312.                         g += 32;
  313.                     if (cb - b > Magic64[v])
  314.                         b += 64;
  315.                  /* clamp error to keep color in range 0 to 255 */
  316.                     r = min(r, 255) & 0xC0;
  317.                     g = min(g, 255) & 0xE0;
  318.                     b = min(b, 255) & 0xC0;
  319.     /* howcome added support for <8 bits 25/1/95 */
  320.     shift = (((7 - (xpos % 8)) % ppb) * depth);
  321.     *dp |= (stdcmap[(r >> 6) | (g >> 3) | (b >> 1)]) << shift;
  322.     if (shift == 0) {
  323. dp++;
  324. newbyte = 1;
  325.     }
  326.                 }
  327.                 else if (imaging == MONO) {
  328.     switch (idata->components) {
  329.       case 1:
  330. cg = Voltage2Brightness(scan_buffer[xpos]);
  331. /* cg = gamma_table[scan_buffer[xpos]]; */
  332. break;
  333.       case 3:
  334. cg = Voltage2Brightness(
  335. (0.59*scan_buffer [0+(xpos * 3)]) +
  336. (0.20*scan_buffer [1+(xpos * 3)]) +
  337. (0.11*scan_buffer [2+(xpos * 3)]));
  338. #if 0
  339. cg = gamma_table[(int)
  340. ((0.59*scan_buffer [0+(xpos * 3)]) +
  341. (0.20*scan_buffer [1+(xpos * 3)]) +
  342. (0.11*scan_buffer [2+(xpos * 3)]))];
  343. #endif
  344. break;
  345.       default:
  346. fprintf(stderr,"ImageOutputScanlines_8, components = %dn",idata->components);
  347.     }
  348.     shift = (((7 - (xpos % 8)) % ppb) * depth);
  349.                     if (cg < Magic256[(row << 4) + col])
  350.                         *dp |= greymap[0] << shift;   /* was *dp++ 17-jan-96 */
  351.                     else
  352.                         *dp |= greymap[15] << shift;  /* idem */
  353.     if (shift == 0) {
  354. dp++;
  355. newbyte = 1;
  356.     }
  357.                 }
  358. else {
  359.     cg = Voltage2Brightness(
  360. (0.59*scan_buffer [0+(xpos * 3)]) +
  361. (0.20*scan_buffer [1+(xpos * 3)]) +
  362. (0.11*scan_buffer [2+(xpos * 3)]));
  363. #if 0
  364.    cg = gamma_table[(int)
  365. ((0.59*scan_buffer [0+(xpos * 3)]) +
  366. (0.20*scan_buffer [1+(xpos * 3)]) +
  367. (0.11*scan_buffer [2+(xpos * 3)]))];
  368. #endif
  369.                     g = cg & 0xF0;
  370.                     if (cg - g > Magic16[(row << 4) + col]) {
  371.                         g += 16;
  372. }
  373.                     g = min(g, 0xF0);
  374.     shift = (((7 - (xpos % 8)) % ppb) * depth);
  375.                     *dp++ |= greymap[g >> 4] << shift;
  376.     if (shift == 0) {
  377. dp++;
  378. newbyte = 1;
  379.     }
  380. }
  381.     }
  382.     if (shift) {
  383. dp++;   /* make sure we start on a new byte for the next line */
  384. newbyte = 1;
  385.     }
  386.         }
  387.     }
  388. }
  389. static int ImageOutputScanlines_8 (output_image_data *output, 
  390. image_data *idata) {
  391.   /*extern int ImageOutputScanlines_8 (output_image_data *output, 
  392. image_data *idata) { */
  393.     /* janet 21/07/95: not used:  unsigned char   c;   */   
  394.     int             v;
  395.     int             xpos = 0, ypos = 0,  yindex; /* janet 21/07/95: not used: pass = 0 */
  396.     unsigned char   *dp, *scan_buffer; /* janet 21/07/95: not used: *dy */
  397.     int             cr=0, cg=0, cb=0, r, g, b, row, col;
  398.     /* janet 21/07/95: not used:     Color           color; */
  399.     if (TRUE) {
  400.         dp = output->data + output->row * output->bytes_per_row;
  401. if (IMAGE_TRACE)
  402.     fprintf(stderr,"ImageOutputScanlines_8 %d %dn", output->row, output->bytes_per_row);
  403.         for (yindex = 0; yindex < idata->rows; yindex++) {
  404.     ypos = yindex + output->row;
  405.     scan_buffer = idata->buffer + (yindex * output->width * idata->components); /* howcome 19/2/95: 3 -> idata->components */
  406.     if (IMAGE_TRACE)
  407. fprintf(stderr,"ImageOutputScanlines: y %d scanbuffer %lxn",yindex, scan_buffer);
  408.             col = ypos & 15;
  409.             for (xpos = 0; xpos < idata->width; ++xpos) {
  410.                 row = xpos & 15;
  411.                 if (imaging == COLOR232) {
  412.     switch (idata->components) {
  413. /* do grayscale */
  414.       case 1:
  415. cr = cg = cb = Voltage2Brightness(scan_buffer[xpos]);
  416. /* cr = cg = cb = gamma_table[scan_buffer[xpos]]; */
  417. g = cg & 0xF0;
  418. if (cg - g > Magic16[(row << 4) + col])
  419.     g += 16;
  420. g = min(g, 0xF0);
  421. *dp++ = greymap[g >> 4];
  422. break;
  423.       case 3:
  424. cr = Voltage2Brightness(scan_buffer [0+(xpos * 3)]);
  425. cg = Voltage2Brightness(scan_buffer [1+(xpos * 3)]);
  426. cb = Voltage2Brightness(scan_buffer [2+(xpos * 3)]);
  427. #if 0
  428. cr = gamma_table[scan_buffer [0+(xpos * 3)]];
  429. cg = gamma_table[scan_buffer [1+(xpos * 3)]];
  430. cb = gamma_table[scan_buffer [2+(xpos * 3)]];
  431. #endif
  432. r = cr & 0xC0;
  433. g = cg & 0xE0;
  434. b = cb & 0xC0;
  435. v = (row << 4) + col;
  436. if (cr - r > Magic64[v])
  437.     r += 64;
  438. if (cg - g > Magic32[v])
  439.     g += 32;
  440. if (cb - b > Magic64[v])
  441.     b += 64;
  442. /* clamp error to keep color in range 0 to 255 */
  443. r = min(r, 255) & 0xC0;
  444. g = min(g, 255) & 0xE0;
  445. b = min(b, 255) & 0xC0;
  446. *dp++ = stdcmap[(r >> 6) | (g >> 3) | (b >> 1)];
  447. break;
  448.       default:
  449. fprintf(stderr,"ImageOutputScanlines_8, components = %dn",idata->components);
  450.     }
  451.                 }
  452.                 else if (imaging == MONO) {
  453.     switch (idata->components) {
  454.       case 1:
  455. cg = Voltage2Brightness(scan_buffer[xpos]);
  456. cg = gamma_table[scan_buffer[xpos]];
  457. break;
  458.       case 3:
  459. cg = Voltage2Brightness(
  460. (0.59*scan_buffer [0+(xpos * 3)]) +
  461. (0.20*scan_buffer [1+(xpos * 3)]) +
  462. (0.11*scan_buffer [2+(xpos * 3)]));
  463. #if 0
  464. cg = gamma_table[(int)
  465. ((0.59*scan_buffer [0+(xpos * 3)]) +
  466. (0.20*scan_buffer [1+(xpos * 3)]) +
  467. (0.11*scan_buffer [2+(xpos * 3)]))];
  468. #endif
  469. break;
  470.       default:
  471. fprintf(stderr,"ImageOutputScanlines_8, components = %dn",idata->components);
  472.     }
  473.                     if (cg < Magic256[(row << 4) + col])
  474.                         *dp++ = greymap[0];
  475.                     else
  476.                         *dp++ = greymap[15];
  477.                 }
  478. else {
  479.     switch (idata->components) {
  480.       case 1:
  481. cg = Voltage2Brightness(scan_buffer[xpos]);
  482. /* cg = gamma_table[scan_buffer[xpos]]; */
  483. break;
  484.       case 3:
  485. cg = Voltage2Brightness(
  486. (0.59*scan_buffer [0+(xpos * 3)]) +
  487. (0.20*scan_buffer [1+(xpos * 3)]) +
  488. (0.11*scan_buffer [2+(xpos * 3)]));
  489. #if 0
  490. cg = gamma_table[(int)
  491. ((0.59*scan_buffer [0+(xpos * 3)]) +
  492. (0.20*scan_buffer [1+(xpos * 3)]) +
  493. (0.11*scan_buffer [2+(xpos * 3)]))];
  494. #endif
  495. break;
  496.       default:
  497. fprintf(stderr,"ImageOutputScanlines_8, components = %dn",idata->components);
  498.     }
  499.                     g = cg & 0xF0;
  500.                     if (cg - g > Magic16[(row << 4) + col]) {
  501.                         g += 16;
  502. }
  503.                     g = min(g, 0xF0);
  504.                     *dp++ = greymap[g >> 4];
  505. }
  506.             }
  507.         }
  508.     }
  509.     return TRUE;  /* janet: added. should it return other value? */
  510. }
  511. static int ImageOutputScanlines_24 (output_image_data *output, 
  512. image_data *idata) {
  513. /*
  514. extern int ImageOutputScanlines_24 (output_image_data *output, 
  515. image_data *idata) { */
  516.   /* janet 24/07/95: not used:    unsigned char   c; */
  517.   /* janet 24/07/95: not used:    int             v; */
  518.     int             xpos = 0, ypos = 0, yindex; /* janet 21/07/95: not used: pass = 0 */
  519.     unsigned char   *dp, *scan_buffer; /* janet 21/07/95: not used: *dy */
  520.     int             row, col; /* janet 21/07/95: not used: cr, cg, cb, r, g, b */
  521.     /* janet 21/07/95: not used:    Color           color; */
  522.     if (TRUE) {
  523.         dp = output->data + output->row * output->bytes_per_row;
  524. if (IMAGE_TRACE)
  525.     fprintf(stderr,"ImageOutputScanlines_24 %d %dn", output->row, output->bytes_per_row);
  526.         for (yindex = 0; yindex < idata->rows; yindex++) {
  527.     ypos = yindex + output->row;
  528.     scan_buffer = idata->buffer + (yindex * output->width * 3);
  529.     if (IMAGE_TRACE)
  530. fprintf(stderr,"ImageOutputScanlines_24: y %d scanbuffer %lxn",yindex, scan_buffer);
  531.             col = ypos & 15;
  532.             for (xpos = 0; xpos < idata->width; ++xpos) {
  533.                 row = xpos & 15;
  534. /*
  535.                 cr = scan_buffer [0+(xpos * 3)];
  536.                 cg = scan_buffer [1+(xpos * 3)];
  537.                 cb = scan_buffer [2+(xpos * 3)];
  538. */
  539.          *dp++ = '';
  540. switch (idata->components) {
  541.   case 1:
  542.     *dp++ = scan_buffer [xpos];
  543.     *dp++ = scan_buffer [xpos];
  544.     *dp++ = scan_buffer [xpos];
  545.     break;
  546.   case 3:
  547.     *dp++ = scan_buffer [((RPixelShift) ? 0 : 2)+(xpos*3)];
  548.     *dp++ = scan_buffer [1+(xpos*3)];
  549.     *dp++ = scan_buffer [((RPixelShift) ? 2 : 0)+(xpos*3)];
  550.     break;
  551.   default:
  552.     fprintf(stderr,"ImageOutputScanlines_8, components = %dn",idata->components);
  553. }
  554.             }
  555.         }
  556.     }
  557.     return TRUE; /* janet 1/8/95: added. should it return other value? */
  558. static int ImageOutputScanlines_16 (output_image_data *output, 
  559. image_data *idata) {
  560.     int             xpos = 0, ypos = 0, yindex;
  561.     unsigned char   *dp, *scan_buffer;
  562.     int             row, col, cr, cg, cb; 
  563.     long            ulp;
  564.   
  565.     if (TRUE) {
  566.         dp = output->data + output->row * output->bytes_per_row;
  567. if (IMAGE_TRACE)
  568.     fprintf(stderr,"ImageOutputScanlines_16 %d %dn", output->row, output->bytes_per_row);
  569.         for (yindex = 0; yindex < idata->rows; yindex++) {
  570.     ypos = yindex + output->row;
  571.     scan_buffer = idata->buffer + (yindex * output->width * 3);
  572.     if (IMAGE_TRACE)
  573. fprintf(stderr,"ImageOutputScanlines_24: y %d scanbuffer %lxn",yindex, scan_buffer);
  574.             col = ypos & 15;
  575.             for (xpos = 0; xpos < idata->width; ++xpos) {
  576.                 row = xpos & 15;
  577. /*
  578.                 cr = scan_buffer [0+(xpos * 3)];
  579.                 cg = scan_buffer [1+(xpos * 3)];
  580.                 cb = scan_buffer [2+(xpos * 3)];
  581. */
  582. switch (idata->components) {
  583.   case 1:
  584.       cr = cg = cb = scan_buffer [xpos];
  585.       GetColor(cr, cg, cb, &ulp);
  586.       *dp++ = ((char*)&ulp)[1]; 
  587.       *dp++ = ((char*)&ulp)[0];
  588.       break;
  589.   case 3:
  590.       cr = scan_buffer [0+(xpos * 3)];
  591.       cg = scan_buffer [1+(xpos * 3)];
  592.       cb = scan_buffer [2+(xpos * 3)];
  593.       GetColor(cr, cg, cb, &ulp);
  594.       *dp++ = ((char*)&ulp)[1]; 
  595.       *dp++ = ((char*)&ulp)[0];
  596.       break; 
  597. default:
  598.     fprintf(stderr,"ImageOutputScanlines_16, components = %dn",idata->components);
  599. }
  600.             }
  601.         }
  602.     }
  603.     return TRUE; /* janet 1/8/95: added. should it return other value? */
  604. #ifdef NEVER
  605. static int ReadColorMap(Block *bp, Image *image, int ncolors, Color *colors, int *grey)
  606. {
  607.     int i, flag, npixels, drb, dgb, dbr;
  608.     unsigned char rgb[3];
  609.     unsigned long pixel, *pixels;
  610.     flag = 1;
  611.     image->npixels = npixels = 0;
  612.     if (imaging == GREY4 || imaging == MONO)
  613.         *grey = flag = 1;
  614.     for (i = 0; i < ncolors; ++i)
  615.     {
  616.         if (! ReadOK(bp, rgb, sizeof(rgb)))
  617.         {
  618.             fprintf(stderr, "bad colormapn");
  619.             return 0;
  620.         }
  621.         colors->red = rgb[0];
  622.         colors->green = rgb[1];
  623.         colors->blue = rgb[2];
  624.      /* apply gamma correction to map voltages to brightness values */
  625.         if (imaging != COLOR888)
  626.         {
  627.             colors->red = Voltage2Brightness(colors->red);
  628.             colors->green = Voltage2Brightness(colors->green);
  629.             colors->blue = Voltage2Brightness(colors->blue);
  630.         }
  631.      /* set grey value iff color is very close to grey (or GREY/MONO imaging) */
  632.         drb = abs(rgb[1] - rgb[0]);
  633.         dgb = abs(rgb[2] - rgb[1]);
  634.         dbr = abs(rgb[0] - rgb[2]);
  635.         if (*grey || (drb < 20 && dgb < 20 && dbr < 20))
  636.         {   
  637.             flag &= 1;
  638.             colors->grey = (3*colors->red + 6*colors->green + colors->blue)/10;
  639.         }
  640.         else
  641.         {
  642.             if (!(*grey))
  643.                 flag = 0;
  644.             colors->grey = 0;
  645.         }
  646.         ++colors;
  647.     }
  648.     *grey = flag;
  649.     return 1;
  650. }
  651. #endif
  652. extern int ImageOutputInit (void *output_in, image_data *data) { 
  653.   /* janet 24/07/95: not used: extern Image *image; */
  654.     output_image_data *output = (output_image_data *) output_in;
  655.     int blocksize;
  656.     /* janet 24/07/95: not used:     int i; */
  657.     output->height = data->height;
  658.     output->width = data->width;
  659.     output->row = 0;
  660.     if ((output->depth == 1) || (output->depth == 2) || (output->depth == 4)) {
  661. int  ppb;
  662.         ppb  = 8/output->depth;
  663.         output->bytes_per_row = data->width/ppb + (data->width%ppb ? 1 : 0); 
  664. /*
  665. fprintf(stderr,"sorry, jpeg images are not supported for depth %dn",depth);
  666. output->data = NULL;
  667. return NULL;
  668. */
  669. }
  670.     else if (output->depth == 8) {
  671. output->bytes_per_row = 1 * data->width;
  672.     }
  673.     else if (output->depth == 16) {
  674.         output->bytes_per_row = 2 * data->width;
  675.     }  
  676.     else if (output->depth == 24) {
  677.         output->bytes_per_row = 4 * data->width;  /* 4 ???? */
  678.     }    
  679.     else {
  680. fprintf(stderr,"sorry, images are not supported for depth %d (%d)n",depth, output->depth);
  681. output->data = NULL;
  682. return FALSE;
  683.     }
  684.     blocksize = output->bytes_per_row * data->height;
  685.     output->data = malloc (blocksize);
  686.     return TRUE; /* janet 1/8/95: added. */
  687. extern int ImageOutputScanlines (void *output_in, image_data *data) { 
  688.     output_image_data *output = (output_image_data *) output_in;
  689.     if (output->data == NULL) {
  690. return FALSE;
  691. }
  692.     else if ((output->depth == 1) || (output->depth == 2) || (output->depth == 4)) {
  693.         ImageOutputScanlines_1_2_4 (output, data);
  694. output->row = output->row + data->rows;
  695. }
  696.     else if (output->depth == 8) {
  697.         ImageOutputScanlines_8 (output, data);
  698. output->row = output->row + data->rows;
  699. }    
  700.     else if (output->depth == 24) {
  701.         ImageOutputScanlines_24 (output, data);
  702. output->row = output->row + data->rows; /* howcome 9/2/94: phill forgot this one */
  703.     else if (output->depth == 16) {
  704.         ImageOutputScanlines_16 (output, data);
  705. output->row = output->row + data->rows;
  706.     else {
  707. fprintf(stderr,"sorry, images are not supported for depth %dn",depth);
  708. return FALSE;
  709. }
  710.     return TRUE;  /* janet 1/8/95: added. */
  711. }