From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- dviware/dvipage/sample.c | 1245 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1245 insertions(+) create mode 100644 dviware/dvipage/sample.c (limited to 'dviware/dvipage/sample.c') diff --git a/dviware/dvipage/sample.c b/dviware/dvipage/sample.c new file mode 100644 index 0000000000..7262e31993 --- /dev/null +++ b/dviware/dvipage/sample.c @@ -0,0 +1,1245 @@ +/* + * dvipage: DVI Previewer Program for Suns + * + * Neil Hunt (hunt@spar.slb.com) + * + * This program is based, in part, upon the program dvisun, + * distributed by the UnixTeX group, extensively modified by + * Neil Hunt at the Schlumberger Palo Alto Research Laboratories + * of Schlumberger Technologies, Inc. + * + * Copyright (c) 1988 Schlumberger Technologies, Inc 1988. + * Anyone can use this software in any manner they choose, + * including modification and redistribution, provided they make + * no charge for it, and these conditions remain unchanged. + * + * This program is distributed as is, with all faults (if any), and + * without any warranty. No author or distributor accepts responsibility + * to anyone for the consequences of using it, or for whether it serves any + * particular purpose at all, or any other reason. + * + * $Log: sample.c,v $ + * Revision 1.1 88/11/28 18:41:24 hunt + * Initial revision + * + * Split out of dvipage.c version 1.4. + */ + +#include +#include /* For MAXPATHLEN */ +#include +#include +#include "dvipage.h" + +forward struct pixrect * pr_alloc(); +forward struct pixrect * pr_free(); +forward struct pixrect * pr_check(); +forward struct pixrect * pr_link(); +forward struct pixrect * pr_sample_4(); +forward struct pixrect * pr_sample_34(); +forward struct pixrect * pr_sample_3(); +forward struct pixrect * pr_sample_2(); + +forward void pw_cover(); +forward void pr_rect(); +forward void pw_rect(); + +/* + * sample_page: + * Filter and sample down page according to current sampling rate, + * and prepare for display. + */ + +void +sample_page() +{ + +#ifdef TIMING + start_time(); +#endif TIMING + + switch(sampling) + { + default: + case 1: + sample_pr = pr_link(&page_mpr, &sample_mpr); + break; + + case 2: + if(! (sample_pr = pr_sample_2(&page_mpr, &sample_mpr))) + message("Out of memory for resampling image"); + break; + + case 3: + if(! (sample_pr = pr_sample_3(&page_mpr, &sample_mpr))) + message("Out of memory for resampling image"); + break; + + case 4: + if(! (sample_pr = pr_sample_4(&page_mpr, &sample_mpr))) + message("Out of memory for resampling image"); + break; + + case 5: + if(! (sample_pr = pr_sample_34(&page_mpr, &sample_mpr))) + message("Out of memory for resampling image"); + break; + } + +#ifdef TIMING + stop_time("Sampling one page"); +#endif TIMING + +} + +/* + * Here follow some functions to deal with pixrects under the special case + * assumption that they are mem_pixrects, where the mpr_data is part + * of a parent structure. + */ + +extern struct pixrectops mem_ops; + +/* + * pr_alloc: + * Allocate memory for a pixrect of size w, h, d. + * Returns a pointer to the pixrect structure. + */ + +struct pixrect * +pr_alloc(mpr, w, h, d) +struct mem_pixrect *mpr; +int w, h, d; +{ + int size; + int linebytes; + short *image; + + /* + * Compute the size of memory needed, and alloc it. + */ + linebytes = mpr_linebytes(w, d); + size = linebytes * h; + if(! (image = (short *)malloc(size))) + return (struct pixrect *)NULL; + + /* + * Set up the pr. + */ + mpr->mpr_pr.pr_ops = &mem_ops; + mpr->mpr_pr.pr_width = w; + mpr->mpr_pr.pr_height = h; + mpr->mpr_pr.pr_depth = d; + mpr->mpr_pr.pr_data = (caddr_t)&mpr->mpr_data; + + /* + * Set up the mpr_data + */ + mpr->mpr_data.md_linebytes = linebytes; + mpr->mpr_data.md_image = image; + mpr->mpr_data.md_offset.x = 0; + mpr->mpr_data.md_offset.y = 0; + mpr->mpr_data.md_primary = TRUE; + mpr->mpr_data.md_flags = 0; + + /* + * Return the pr. + */ + return &mpr->mpr_pr; +} + +/* + * pr_free: + * Free the memory associated with a pixrect. + * Returns a pointer to no pixrect structure. + */ + +struct pixrect * +pr_free(mpr) +struct mem_pixrect *mpr; +{ + short *image; + + if((image = mpr->mpr_data.md_image)) + { + if(mpr->mpr_data.md_primary) + free(image); + mpr->mpr_data.md_image = (short *)NULL; + } + mpr->mpr_pr.pr_width = 0; + mpr->mpr_pr.pr_height = 0; + + return (struct pixrect *)NULL; +} + +/* + * pr_check: + * Check that a designated pixrect has memory allocated for an image + * of size w, h, d. If not, free any existing memory and allocate + * more memory. This is equivalent to, but much faster than, a + * sequence of + * pr_destroy(mpr); + * mpr = mem_create(w, h, d); + */ + +struct pixrect * +pr_check(mpr, w, h, d) +struct mem_pixrect *mpr; +int w, h, d; +{ + /* + * If there is an image, check that it is the correct size. + */ + if(mpr->mpr_data.md_image) + { + if(mpr->mpr_pr.pr_width == w && + mpr->mpr_pr.pr_height == h && + mpr->mpr_pr.pr_depth == d) + return &mpr->mpr_pr; + + (void)pr_free(mpr); + } + + return pr_alloc(mpr, w, h, d); +} + +/* + * pr_link: + * Link the memory of mpr1 to mpr2, making mpr2 a secondary pixrect. + */ + +struct pixrect * +pr_link(mpr1, mpr2) +struct mem_pixrect *mpr1; +struct mem_pixrect *mpr2; +{ + /* + * Free the existing memory, if any. + */ + (void)pr_free(mpr2); + + /* + * Set up the pr. + */ + mpr2->mpr_pr.pr_ops = &mem_ops; + mpr2->mpr_pr.pr_width = mpr1->mpr_pr.pr_width; + mpr2->mpr_pr.pr_height = mpr1->mpr_pr.pr_height; + mpr2->mpr_pr.pr_depth = mpr1->mpr_pr.pr_depth; + mpr2->mpr_pr.pr_data = (caddr_t)&mpr2->mpr_data; + + /* + * Set up the mpr_data + */ + mpr2->mpr_data.md_linebytes = mpr1->mpr_data.md_linebytes; + mpr2->mpr_data.md_image = mpr1->mpr_data.md_image; + mpr2->mpr_data.md_offset.x = mpr1->mpr_data.md_offset.x; + mpr2->mpr_data.md_offset.y = mpr1->mpr_data.md_offset.y; + mpr2->mpr_data.md_primary = FALSE; + mpr2->mpr_data.md_flags = 0; + + /* + * Return the pr. + */ + return &mpr2->mpr_pr; +} + +/* + * Colour Map Stuff + * ================ + */ + +#define M4F 0 +#define M4T (M4F+16) +#define M3F (M4T+1) +#define M3T (M3F+24) +#define M2F (M3T+1) +#define M2T (M2F+4) + +uchar cmap_red[64] = +{ +#ifdef NEVER + /* Cmap with GAMMA=2,2,2,20,20,20 */ + /* 4x4 from 0 to 16 */ + 255, 247, 239, 231, 223, 214, 205, 196, 186, + 175, 163, 151, 137, 121, 103, 78, 20, + + /* 3x3 from 17 to 41 */ + 255, 250, 244, 239, 234, 229, 223, 217, 211, + 205, 199, 192, 186, 179, 171, 163, 155, + 146, 137, 127, 115, 103, 87, 67, 20, + + /* 2x2 from 42 to 46 */ + 255, 223, 186, 137, 20, + + /* spare */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#endif NEVER + /* Cmap with GAMMA=1.3,1.3,1.3,0,0,0 */ + /* 4x4 from 0 to 16 */ + 255, 242, 230, 217, 204, 191, 177, 163, 149, + 135, 119, 104, 87, 70, 51, 30, 0, + + /* 3x3 from 17 to 41 */ + 255, 246, 238, 230, 221, 213, 204, 195, 186, + 177, 168, 159, 149, 139, 130, 119, 109, + 98, 87, 76, 64, 51, 37, 22, 0, + + /* 2x2 from 42 to 46 */ + 255, 204, 149, 87, 0, + + /* spare */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +uchar cmap_green[64] = +{ + /* 4x4 from 0 to 16 */ + 255, 242, 230, 217, 204, 191, 177, 163, 149, + 135, 119, 104, 87, 70, 51, 30, 0, + + /* 3x3 from 17 to 41 */ + 255, 246, 238, 230, 221, 213, 204, 195, 186, + 177, 168, 159, 149, 139, 130, 119, 109, + 98, 87, 76, 64, 51, 37, 22, 0, + + /* 2x2 from 42 to 46 */ + 255, 204, 149, 87, 0, + + /* spare */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +uchar cmap_blue[64] = +{ + /* 4x4 from 0 to 16 */ + 255, 242, 230, 217, 204, 191, 177, 163, 149, + 135, 119, 104, 87, 70, 51, 30, 0, + + /* 3x3 from 17 to 41 */ + 255, 246, 238, 230, 221, 213, 204, 195, 186, + 177, 168, 159, 149, 139, 130, 119, 109, + 98, 87, 76, 64, 51, 37, 22, 0, + + /* 2x2 from 42 to 46 */ + 255, 204, 149, 87, 0, + + /* spare */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +double gamma_red = 2.0; +double gamma_green = 2.0; +double gamma_blue = 2.0; +int min_red = 20; +int min_green = 20; +int min_blue = 20; + +forward void make_one_cmap(); + +void +make_cmap() +{ + char *e; + + if((e = getenv("DVIPAGE_GAMMA")) == NULL) + return; + + min_red = 20; + min_green = 20; + min_blue = 20; + gamma_red = 0.0; + gamma_green = 0.0; + gamma_blue = 0.0; + + (void)sscanf(e, " %lf,%lf,%lf,%d,%d,%d ", + &gamma_red, &gamma_green, &gamma_blue, + &min_red, &min_green, &min_blue); + + if(gamma_red == 0.0) + gamma_red = 1.3; + if(gamma_green == 0.0) + gamma_green = gamma_red; + if(gamma_blue == 0.0) + gamma_blue = gamma_red; + + make_one_cmap(cmap_red, 1.0/gamma_red, min_red); + make_one_cmap(cmap_green, 1.0/gamma_green, min_green); + make_one_cmap(cmap_blue, 1.0/gamma_blue, min_blue); +} + +void +make_one_cmap(cmap, power, mn) +uchar cmap[]; +double power; +int mn; +{ + int i; + + /* + * 4x4 cmap. + */ + for(i = M4F; i <= M4T; i++) + cmap[i] = (uchar)(pow((double)(M4T - i) / (M4T - M4F), power) + * (255 - mn) + mn); + + /* + * 3x3 cmap. + */ + for(i = M3F; i <= M3T; i++) + cmap[i] = (uchar)(pow((double)(M3T - i) / (M3T - M3F), power) + * (255 - mn) + mn); + + /* + * 2x2 cmap. + */ + for(i = M2F; i <= M2T; i++) + cmap[i] = (uchar)(pow((double)(M2T - i) / (M2T - M2F), power) + * (255 - mn) + mn); + + cmap[63] = mn; +} + +/* + * Tally table used to compute the number of bits in packed words. + * This is used in computing the number of bits in a 4x4 region of + * a packed image. + * + * The packed word is used as an index into this table; + * The most significant 16 bits of the value obtained represent the + * number of bits in the upper half of the index, with each bit counted + * with a weight of 15. + * The least significant 16 bits of the value obtained represent the + * number of bits in the l;ower hald of the index, with each bit counted + * with a weight of 15. + * + * By combining the upper and lower halves in a single word, the values + * for the four vertically adjacent words can be combined with each other + * in a single addition per word, adding simultaneously both the tallies + * for the left and the right halves of the word. + */ + +static int tally4[] = +{ + 0x00000000, 0x00000001, 0x00000001, 0x00000002, + 0x00000001, 0x00000002, 0x00000002, 0x00000003, + 0x00000001, 0x00000002, 0x00000002, 0x00000003, + 0x00000002, 0x00000003, 0x00000003, 0x00000004, + 0x00010000, 0x00010001, 0x00010001, 0x00010002, + 0x00010001, 0x00010002, 0x00010002, 0x00010003, + 0x00010001, 0x00010002, 0x00010002, 0x00010003, + 0x00010002, 0x00010003, 0x00010003, 0x00010004, + 0x00010000, 0x00010001, 0x00010001, 0x00010002, + 0x00010001, 0x00010002, 0x00010002, 0x00010003, + 0x00010001, 0x00010002, 0x00010002, 0x00010003, + 0x00010002, 0x00010003, 0x00010003, 0x00010004, + 0x00020000, 0x00020001, 0x00020001, 0x00020002, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020002, 0x00020003, 0x00020003, 0x00020004, + 0x00010000, 0x00010001, 0x00010001, 0x00010002, + 0x00010001, 0x00010002, 0x00010002, 0x00010003, + 0x00010001, 0x00010002, 0x00010002, 0x00010003, + 0x00010002, 0x00010003, 0x00010003, 0x00010004, + 0x00020000, 0x00020001, 0x00020001, 0x00020002, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020002, 0x00020003, 0x00020003, 0x00020004, + 0x00020000, 0x00020001, 0x00020001, 0x00020002, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020002, 0x00020003, 0x00020003, 0x00020004, + 0x00030000, 0x00030001, 0x00030001, 0x00030002, + 0x00030001, 0x00030002, 0x00030002, 0x00030003, + 0x00030001, 0x00030002, 0x00030002, 0x00030003, + 0x00030002, 0x00030003, 0x00030003, 0x00030004, + 0x00010000, 0x00010001, 0x00010001, 0x00010002, + 0x00010001, 0x00010002, 0x00010002, 0x00010003, + 0x00010001, 0x00010002, 0x00010002, 0x00010003, + 0x00010002, 0x00010003, 0x00010003, 0x00010004, + 0x00020000, 0x00020001, 0x00020001, 0x00020002, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020002, 0x00020003, 0x00020003, 0x00020004, + 0x00020000, 0x00020001, 0x00020001, 0x00020002, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020002, 0x00020003, 0x00020003, 0x00020004, + 0x00030000, 0x00030001, 0x00030001, 0x00030002, + 0x00030001, 0x00030002, 0x00030002, 0x00030003, + 0x00030001, 0x00030002, 0x00030002, 0x00030003, + 0x00030002, 0x00030003, 0x00030003, 0x00030004, + 0x00020000, 0x00020001, 0x00020001, 0x00020002, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020001, 0x00020002, 0x00020002, 0x00020003, + 0x00020002, 0x00020003, 0x00020003, 0x00020004, + 0x00030000, 0x00030001, 0x00030001, 0x00030002, + 0x00030001, 0x00030002, 0x00030002, 0x00030003, + 0x00030001, 0x00030002, 0x00030002, 0x00030003, + 0x00030002, 0x00030003, 0x00030003, 0x00030004, + 0x00030000, 0x00030001, 0x00030001, 0x00030002, + 0x00030001, 0x00030002, 0x00030002, 0x00030003, + 0x00030001, 0x00030002, 0x00030002, 0x00030003, + 0x00030002, 0x00030003, 0x00030003, 0x00030004, + 0x00040000, 0x00040001, 0x00040001, 0x00040002, + 0x00040001, 0x00040002, 0x00040002, 0x00040003, + 0x00040001, 0x00040002, 0x00040002, 0x00040003, + 0x00040002, 0x00040003, 0x00040003, 0x00040004, +}; + +/* + * Tally table used to compute the number of bits in packed words. + * This is used in computing the number of bits in a 3x3 region of + * a packed image. + * + * The packed word is used as an index into this table; + * Bits 23..16 of the value obtained represent the number of bits in + * the upper 2.67 bits of the index, with each bit counted with a weight + * of 15. etc. etc. + * + * By combining the three parts in a single word, the values + * for the three vertically adjacent words can be combined with each other + * in a single addition per word, adding simultaneously both the tallies + * for the left and the right halves of the word. + */ + +static int tally3[] = +{ + 0x00000000, 0x00000003, 0x00000003, 0x00000006, + 0x00000102, 0x00000105, 0x00000105, 0x00000108, + 0x00000300, 0x00000303, 0x00000303, 0x00000306, + 0x00000402, 0x00000405, 0x00000405, 0x00000408, + 0x00000300, 0x00000303, 0x00000303, 0x00000306, + 0x00000402, 0x00000405, 0x00000405, 0x00000408, + 0x00000600, 0x00000603, 0x00000603, 0x00000606, + 0x00000702, 0x00000705, 0x00000705, 0x00000708, + 0x00020100, 0x00020103, 0x00020103, 0x00020106, + 0x00020202, 0x00020205, 0x00020205, 0x00020208, + 0x00020400, 0x00020403, 0x00020403, 0x00020406, + 0x00020502, 0x00020505, 0x00020505, 0x00020508, + 0x00020400, 0x00020403, 0x00020403, 0x00020406, + 0x00020502, 0x00020505, 0x00020505, 0x00020508, + 0x00020700, 0x00020703, 0x00020703, 0x00020706, + 0x00020802, 0x00020805, 0x00020805, 0x00020808, + 0x00030000, 0x00030003, 0x00030003, 0x00030006, + 0x00030102, 0x00030105, 0x00030105, 0x00030108, + 0x00030300, 0x00030303, 0x00030303, 0x00030306, + 0x00030402, 0x00030405, 0x00030405, 0x00030408, + 0x00030300, 0x00030303, 0x00030303, 0x00030306, + 0x00030402, 0x00030405, 0x00030405, 0x00030408, + 0x00030600, 0x00030603, 0x00030603, 0x00030606, + 0x00030702, 0x00030705, 0x00030705, 0x00030708, + 0x00050100, 0x00050103, 0x00050103, 0x00050106, + 0x00050202, 0x00050205, 0x00050205, 0x00050208, + 0x00050400, 0x00050403, 0x00050403, 0x00050406, + 0x00050502, 0x00050505, 0x00050505, 0x00050508, + 0x00050400, 0x00050403, 0x00050403, 0x00050406, + 0x00050502, 0x00050505, 0x00050505, 0x00050508, + 0x00050700, 0x00050703, 0x00050703, 0x00050706, + 0x00050802, 0x00050805, 0x00050805, 0x00050808, + 0x00030000, 0x00030003, 0x00030003, 0x00030006, + 0x00030102, 0x00030105, 0x00030105, 0x00030108, + 0x00030300, 0x00030303, 0x00030303, 0x00030306, + 0x00030402, 0x00030405, 0x00030405, 0x00030408, + 0x00030300, 0x00030303, 0x00030303, 0x00030306, + 0x00030402, 0x00030405, 0x00030405, 0x00030408, + 0x00030600, 0x00030603, 0x00030603, 0x00030606, + 0x00030702, 0x00030705, 0x00030705, 0x00030708, + 0x00050100, 0x00050103, 0x00050103, 0x00050106, + 0x00050202, 0x00050205, 0x00050205, 0x00050208, + 0x00050400, 0x00050403, 0x00050403, 0x00050406, + 0x00050502, 0x00050505, 0x00050505, 0x00050508, + 0x00050400, 0x00050403, 0x00050403, 0x00050406, + 0x00050502, 0x00050505, 0x00050505, 0x00050508, + 0x00050700, 0x00050703, 0x00050703, 0x00050706, + 0x00050802, 0x00050805, 0x00050805, 0x00050808, + 0x00060000, 0x00060003, 0x00060003, 0x00060006, + 0x00060102, 0x00060105, 0x00060105, 0x00060108, + 0x00060300, 0x00060303, 0x00060303, 0x00060306, + 0x00060402, 0x00060405, 0x00060405, 0x00060408, + 0x00060300, 0x00060303, 0x00060303, 0x00060306, + 0x00060402, 0x00060405, 0x00060405, 0x00060408, + 0x00060600, 0x00060603, 0x00060603, 0x00060606, + 0x00060702, 0x00060705, 0x00060705, 0x00060708, + 0x00080100, 0x00080103, 0x00080103, 0x00080106, + 0x00080202, 0x00080205, 0x00080205, 0x00080208, + 0x00080400, 0x00080403, 0x00080403, 0x00080406, + 0x00080502, 0x00080505, 0x00080505, 0x00080508, + 0x00080400, 0x00080403, 0x00080403, 0x00080406, + 0x00080502, 0x00080505, 0x00080505, 0x00080508, + 0x00080700, 0x00080703, 0x00080703, 0x00080706, + 0x00080802, 0x00080805, 0x00080805, 0x00080808, +}; + +/* + * Tally table used to compute the number of bits in packed words. + * This is used in computing the number of bits in a 2x2 region of + * a packed image. + * + * The packed word is used as an index into this table; + * The most significant 8 bits of the value obtained represent the + * number of bits in the upper half of the index, with each bit counted + * with a weight of 15. + * ... + * The least significant 8 bits of the value obtained represent the + * number of bits in the l;ower hald of the index, with each bit counted + * with a weight of 15. + * + * By combining the four pairs of tallies in a single word, the values + * for the two vertically adjacent words can be combined with each other + * in a single addition per word, adding simultaneously all four tallies + * for the four pairs of the word. + */ + +static int tally2[] = +{ + 0x00000000, 0x00000001, 0x00000001, 0x00000002, + 0x00000100, 0x00000101, 0x00000101, 0x00000102, + 0x00000100, 0x00000101, 0x00000101, 0x00000102, + 0x00000200, 0x00000201, 0x00000201, 0x00000202, + 0x00010000, 0x00010001, 0x00010001, 0x00010002, + 0x00010100, 0x00010101, 0x00010101, 0x00010102, + 0x00010100, 0x00010101, 0x00010101, 0x00010102, + 0x00010200, 0x00010201, 0x00010201, 0x00010202, + 0x00010000, 0x00010001, 0x00010001, 0x00010002, + 0x00010100, 0x00010101, 0x00010101, 0x00010102, + 0x00010100, 0x00010101, 0x00010101, 0x00010102, + 0x00010200, 0x00010201, 0x00010201, 0x00010202, + 0x00020000, 0x00020001, 0x00020001, 0x00020002, + 0x00020100, 0x00020101, 0x00020101, 0x00020102, + 0x00020100, 0x00020101, 0x00020101, 0x00020102, + 0x00020200, 0x00020201, 0x00020201, 0x00020202, + 0x01000000, 0x01000001, 0x01000001, 0x01000002, + 0x01000100, 0x01000101, 0x01000101, 0x01000102, + 0x01000100, 0x01000101, 0x01000101, 0x01000102, + 0x01000200, 0x01000201, 0x01000201, 0x01000202, + 0x01010000, 0x01010001, 0x01010001, 0x01010002, + 0x01010100, 0x01010101, 0x01010101, 0x01010102, + 0x01010100, 0x01010101, 0x01010101, 0x01010102, + 0x01010200, 0x01010201, 0x01010201, 0x01010202, + 0x01010000, 0x01010001, 0x01010001, 0x01010002, + 0x01010100, 0x01010101, 0x01010101, 0x01010102, + 0x01010100, 0x01010101, 0x01010101, 0x01010102, + 0x01010200, 0x01010201, 0x01010201, 0x01010202, + 0x01020000, 0x01020001, 0x01020001, 0x01020002, + 0x01020100, 0x01020101, 0x01020101, 0x01020102, + 0x01020100, 0x01020101, 0x01020101, 0x01020102, + 0x01020200, 0x01020201, 0x01020201, 0x01020202, + 0x01000000, 0x01000001, 0x01000001, 0x01000002, + 0x01000100, 0x01000101, 0x01000101, 0x01000102, + 0x01000100, 0x01000101, 0x01000101, 0x01000102, + 0x01000200, 0x01000201, 0x01000201, 0x01000202, + 0x01010000, 0x01010001, 0x01010001, 0x01010002, + 0x01010100, 0x01010101, 0x01010101, 0x01010102, + 0x01010100, 0x01010101, 0x01010101, 0x01010102, + 0x01010200, 0x01010201, 0x01010201, 0x01010202, + 0x01010000, 0x01010001, 0x01010001, 0x01010002, + 0x01010100, 0x01010101, 0x01010101, 0x01010102, + 0x01010100, 0x01010101, 0x01010101, 0x01010102, + 0x01010200, 0x01010201, 0x01010201, 0x01010202, + 0x01020000, 0x01020001, 0x01020001, 0x01020002, + 0x01020100, 0x01020101, 0x01020101, 0x01020102, + 0x01020100, 0x01020101, 0x01020101, 0x01020102, + 0x01020200, 0x01020201, 0x01020201, 0x01020202, + 0x02000000, 0x02000001, 0x02000001, 0x02000002, + 0x02000100, 0x02000101, 0x02000101, 0x02000102, + 0x02000100, 0x02000101, 0x02000101, 0x02000102, + 0x02000200, 0x02000201, 0x02000201, 0x02000202, + 0x02010000, 0x02010001, 0x02010001, 0x02010002, + 0x02010100, 0x02010101, 0x02010101, 0x02010102, + 0x02010100, 0x02010101, 0x02010101, 0x02010102, + 0x02010200, 0x02010201, 0x02010201, 0x02010202, + 0x02010000, 0x02010001, 0x02010001, 0x02010002, + 0x02010100, 0x02010101, 0x02010101, 0x02010102, + 0x02010100, 0x02010101, 0x02010101, 0x02010102, + 0x02010200, 0x02010201, 0x02010201, 0x02010202, + 0x02020000, 0x02020001, 0x02020001, 0x02020002, + 0x02020100, 0x02020101, 0x02020101, 0x02020102, + 0x02020100, 0x02020101, 0x02020101, 0x02020102, + 0x02020200, 0x02020201, 0x02020201, 0x02020202, +}; + +/* + * P_row: + * Access macro for obtaining a pointer to the bytes of a pixrect + * starting at row `row'. + */ + +#define P_row(mpr, row) \ + (uchar *)((int)((mpr)->mpr_data.md_image) + \ + (int)((short)(row) * (short)((mpr)->mpr_data.md_linebytes))); + +/* + * pr_sample_4: + * Filter and sample mpr1 on a 4x4 basis into mpr2. + */ + +struct pixrect * +pr_sample_4(mpr1, mpr2) +struct mem_pixrect *mpr1; +struct mem_pixrect *mpr2; +{ + int cols, rows; + int j; + register uchar *p0; /* a5 */ + register uchar *p1; /* a4 */ + register uchar *p2; /* a3 */ + register uchar *p3; /* a2 */ + register uchar *pr; + register uchar *er; + register int tallies; /* d7 */ + int line_offset; + + cols = mpr1->mpr_pr.pr_width / 4; + rows = mpr1->mpr_pr.pr_height / 4; + + if(verbose & DEBUG_IMSIZE) + fprintf(stderr, "pr_sample_4: (%d x %d) -> (%d x %d)\n", + mpr1->mpr_pr.pr_width, mpr1->mpr_pr.pr_height, cols, rows); + + /* + * Allocate output image. + */ + if(! pr_check(mpr2, cols, rows, 8)) + return (struct pixrect *)NULL; + + /* + * Do the sampling. + */ + line_offset = mpr1->mpr_data.md_linebytes; + for(j = 0; j < rows; j++) + { + p0 = P_row(mpr1, j*4); + p1 = p0 + line_offset; + p2 = p1 + line_offset; + p3 = p2 + line_offset; + + pr = P_row(mpr2, j); + + for(er = pr + cols; pr < er; ) + { + /* + * Test for all zero. + if(*p0 == 0 && *p1 == 0 && *p2 == 0 && *p3 == 0) + { + *pr++ = 0; + + if(pr >= er) + break; + + *pr++ = 0; + } + else + */ + { + tallies = + tally4[*p0] + + tally4[*p1] + + tally4[*p2] + + tally4[*p3]; + + /* + * High order 4 bits + */ + *pr++ = (tallies >> 16) + M4F; + + if(pr >= er) + break; + + /* + * Low order 4 bits + */ + *pr++ = tallies + M4F; + } + p0++; + p1++; + p2++; + p3++; + } + } + + return &mpr2->mpr_pr; +} + +/* + * pr_sample_34: + * Filter and sample mpr1 on a 2.67x4 basis into mpr2. + * Tally count uses M3 table, and gets up to 32 pixels (weighted at 1/3) + * divides by two to index into the 0..16 M4 table. + */ + +struct pixrect * +pr_sample_34(mpr1, mpr2) +struct mem_pixrect *mpr1; +struct mem_pixrect *mpr2; +{ + int cols, rows; + int j; + register uchar *p0; /* a5 */ + register uchar *p1; /* a4 */ + register uchar *p2; /* a3 */ + register uchar *p3; /* a2 */ + register uchar *pr; + register uchar *er; + register int tallies; /* d7 */ + int line_offset; + + cols = mpr1->mpr_pr.pr_width * 3 / 8; + rows = mpr1->mpr_pr.pr_height / 4; + + if(verbose & DEBUG_IMSIZE) + fprintf(stderr, "pr_sample_34: (%d x %d) -> (%d x %d)\n", + mpr1->mpr_pr.pr_width, mpr1->mpr_pr.pr_height, cols, rows); + + /* + * Allocate output image. + */ + if(! pr_check(mpr2, cols, rows, 8)) + return (struct pixrect *)NULL; + + /* + * Do the sampling. + */ + line_offset = mpr1->mpr_data.md_linebytes; + for(j = 0; j < rows; j++) + { + p0 = P_row(mpr1, j*4); + p1 = p0 + line_offset; + p2 = p1 + line_offset; + p3 = p2 + line_offset; + + pr = P_row(mpr2, j); + + for(er = pr + cols; pr < er; ) + { + /* + * Test for all zero. + if(*p0 == 0 && *p1 == 0 && *p2 == 0) + { + *pr++ = 0; + + if(pr >= er) + break; + + *pr++ = 0; + + if(pr >= er) + break; + + *pr++ = 0; + } + else + */ + { + tallies = + tally3[*p0] + + tally3[*p1] + + tally3[*p2] + + tally3[*p3]; + + /* + * High order 3 bits + */ + *pr++ = (tallies >> (16+1)) + M4F; + + if(pr >= er) + break; + + *pr++ = (tallies >> (8+1)) + M4F; + + if(pr >= er) + break; + + /* + * Low order 3 bits + */ + *pr++ = (tallies >> 1) + M4F; + } + p0++; + p1++; + p2++; + p3++; + } + } + + return &mpr2->mpr_pr; +} + +/* + * pr_sample_3: + * Filter and sample mpr1 on a 3x3 basis into mpr2. + * Note that the horizontal sampling is actually 3/8 rather than 1/3. + */ + +struct pixrect * +pr_sample_3(mpr1, mpr2) +struct mem_pixrect *mpr1; +struct mem_pixrect *mpr2; +{ + int cols, rows; + int j; + register uchar *p0; /* a5 */ + register uchar *p1; /* a4 */ + register uchar *p2; /* a3 */ + register uchar *pr; /* a2 */ + register uchar *er; + register int tallies; /* d7 */ + int line_offset; + + cols = mpr1->mpr_pr.pr_width * 3 / 8; + rows = mpr1->mpr_pr.pr_height / 3; + + if(verbose & DEBUG_IMSIZE) + fprintf(stderr, "pr_sample_3: (%d x %d) -> (%d x %d)\n", + mpr1->mpr_pr.pr_width, mpr1->mpr_pr.pr_height, cols, rows); + + /* + * Allocate output image. + */ + if(! pr_check(mpr2, cols, rows, 8)) + return (struct pixrect *)NULL; + + /* + * Do the sampling. + */ + line_offset = mpr1->mpr_data.md_linebytes; + for(j = 0; j < rows; j++) + { + p0 = P_row(mpr1, j*3); + p1 = p0 + line_offset; + p2 = p1 + line_offset; + + pr = P_row(mpr2, j); + + for(er = pr + cols; pr < er; ) + { + /* + * Test for all zero. + if(*p0 == 0 && *p1 == 0 && *p2 == 0) + { + *pr++ = 0; + + if(pr >= er) + break; + + *pr++ = 0; + + if(pr >= er) + break; + + *pr++ = 0; + } + else + */ + { + tallies = + tally3[*p0] + + tally3[*p1] + + tally3[*p2]; + + /* + * High order 3 bits + */ + *pr++ = (tallies >> 16) + M3F; + + if(pr >= er) + break; + + *pr++ = (tallies >> 8) + M3F; + + if(pr >= er) + break; + + /* + * Low order 3 bits + */ + *pr++ = tallies + M3F; + } + p0++; + p1++; + p2++; + } + } + + return &mpr2->mpr_pr; +} + +/* + * pr_sample_2: + * Filter and sample mpr1 on a 2x2 basis into mpr2. + */ + +struct pixrect * +pr_sample_2(mpr1, mpr2) +struct mem_pixrect *mpr1; +struct mem_pixrect *mpr2; +{ + int cols, rows; + int j; + register uchar *p0; /* a5 */ + register uchar *p1; /* a4 */ + register uchar *pr; /* a3 */ + register uchar *er; /* a2 */ + register int tallies; /* d7 */ + int line_offset; + + cols = mpr1->mpr_pr.pr_width / 2; + rows = mpr1->mpr_pr.pr_height / 2; + + if(verbose & DEBUG_IMSIZE) + fprintf(stderr, "pr_sample_2: (%d x %d) -> (%d x %d)\n", + mpr1->mpr_pr.pr_width, mpr1->mpr_pr.pr_height, cols, rows); + + /* + * Allocate output image. + */ + if(! pr_check(mpr2, cols, rows, 8)) + return (struct pixrect *)NULL; + + /* + * Do the sampling. + */ + line_offset = mpr1->mpr_data.md_linebytes; + for(j = 0; j < rows; j++) + { + p0 = P_row(mpr1, j*2); + p1 = p0 + line_offset; + + pr = P_row(mpr2, j); + + for(er = pr + cols; pr < er; ) + { + /* + * Test for all zero. + if(*p0 == 0 && *p1 == 0) + { + *pr++ = 0; + + if(pr >= er) + break; + + *pr++ = 0; + + if(pr >= er) + break; + + *pr++ = 0; + + if(pr >= er) + break; + + *pr++ = 0; + } + else + */ + { + tallies = + tally2[*p0] + + tally2[*p1]; + + /* + * Highest two bits + */ + *pr++ = (tallies >> 24) + M2F; + + if(pr >= er) + break; + + *pr++ = (tallies >> 16) + M2F; + + if(pr >= er) + break; + + *pr++ = (tallies >> 8) + M2F; + + if(pr >= er) + break; + + /* + * Lowest two bits + */ + *pr++ = tallies + M2F; + } + p0++; + p1++; + } + } + + return &mpr2->mpr_pr; +} + +/* + * pw_cover: + * Function which writes a pixrect onto a pixwin; + * where there are no src pixels, it writes background colour. + */ + +void +pw_cover(dpw, dx, dy, dw, dh, op, spr, sx, sy) +Pixwin *dpw; +int dx, dy, dw, dh; +int op; +Pixrect *spr; +int sx, sy; +{ + int aw, ah; + + /* + * Handle the left margin. + * If the left margin is less than the width to be painted, + * paint a margin, else paint the whole region and return. + */ + if(sx < 0) + { + if(-sx < dw) + { + pw_writebackground(dpw, dx, dy, -sx, dh, op); + dx -= sx; + sx = 0; + dw += sx; + } + else + { + pw_writebackground(dpw, dx, dy, dw, dh, op); + return; + } + } + + /* + * Handle the top margin. + * If the top margin is less thatn the width to be painted, + * paint a margin, else paint the whole region and return. + */ + if(sy < 0) + { + if(-sy < dh) + { + pw_writebackground(dpw, dx, dy, dw, -sy, op); + dy -= sy; + sy = 0; + dh += sy; + } + else + { + pw_writebackground(dpw, dx, dy, dw, dh, op); + return; + } + } + + /* + * Handle the right margin. + * aw = available width of source image. + * If available width > 0 paint a margin of dw-aw width, + * otherwise paint the whole region. + */ + aw = spr->pr_width-sx; + if(dw > aw) + { + if(aw > 0) + { + pw_writebackground(dpw, dx+aw, dy, dw-aw, dh, op); + dw = aw; + } + else + { + pw_writebackground(dpw, dx, dy, dw, dh, op); + return; + } + } + + /* + * Handle the bottom margin. + * ah = available height of source image. + * If available height > 0 paint a margin of dh-ah height, + * otherwise paint the whole region. + */ + ah = spr->pr_height-sy; + if(dh > ah) + { + if(ah > 0) + { + pw_writebackground(dpw, dx, dy+ah, dw, dh-ah, op); + dh = ah; + } + else + { + pw_writebackground(dpw, dx, dy, dw, dh, op); + return; + } + } + + /* + * Paint the image. + */ + pw_write(dpw, dx, dy, dw, dh, op, spr, sx, sy); +} + +/* + * pr_rect: + * Draws a box with op and colour as specified. + */ + +void +pr_rect(pr, x, y, w, h, t, op, value) +struct pixrect *pr; +int x, y, w, h; +int t; +int op, value; +{ + int i; + + for(i = 0; i < t; i++) + { + pr_vector(pr, x, y, x+w-1, y, op, value); + pr_vector(pr, x+w-1, y+1, x+w-1, y+h-2, op, value); + pr_vector(pr, x, y+h-1, x+w-1, y+h-1, op, value); + pr_vector(pr, x, y+1, x, y+h-2, op, value); + + x += 1; + y += 1; + w -= 2; + h -= 2; + + if(w <= 0 || h <= 0) + break; + } +} + +/* + * pw_rect: + * Draws a box with op and colour as specified. + */ + +void +pw_rect(pw, x, y, w, h, t, op, value) +Pixwin *pw; +int x, y, w, h; +int t; +int op, value; +{ + int i; + Rect r; + + r.r_left = x; + r.r_top = y; + r.r_width = w; + r.r_height = h; + pw_lock(pw, &r); + + for(i = 0; i < t; i++) + { + pw_vector(pw, x, y, x+w-1, y, op, value); + pw_vector(pw, x+w-1, y+1, x+w-1, y+h-2, op, value); + pw_vector(pw, x, y+h-1, x+w-1, y+h-1, op, value); + pw_vector(pw, x, y+1, x, y+h-2, op, value); + + x += 1; + y += 1; + w -= 2; + h -= 2; + + if(w <= 0 || h <= 0) + break; + } + + pw_unlock(pw); +} -- cgit v1.2.3