Exemple #1
0
/* Find the index of the point with the smallest y.also return the
 * smallest and largest y */
static int GetFPolyYBounds(register SppPointPtr pts, int n, double yFtrans, int* by, int* ty)
{
    register SppPointPtr        ptMin;
    double                         ymin, ymax;
    SppPointPtr                        ptsStart = pts;

    ptMin = pts;
    ymin = ymax = (pts++)->y;

    while (--n > 0) {
        if (pts->y < ymin)
        {
            ptMin = pts;
            ymin = pts->y;
        }
        if(pts->y > ymax)
            ymax = pts->y;

        pts++;
    }

    *by = ICEIL(ymin + yFtrans);
    *ty = ICEIL(ymax + yFtrans - 1);
    return(ptMin-ptsStart);
}
Exemple #2
0
Image::Image(std::string path) {
	
	std::ifstream stream;
	stream.open(path.c_str(), std::ios::binary);
	stream.read(this->type, 2);
	stream.read((char *)&this->size, 4);
	stream.read((char *)&this->reserved1, 2);
	stream.read((char *)&this->reserved2, 2);
	stream.read((char *)&this->offset_bits, 4);
	stream.read((char *)&this->header_size, 4);
	stream.read((char *)&this->width, 4);
	stream.read((char *)&this->height, 4);
	stream.read((char *)&this->planes, 2);
	stream.read((char *)&this->bit_count, 2);
	stream.read((char *)&this->compression, 4);
	stream.read((char *)&this->image_size, 4);
	stream.read((char *)&this->x_pixel_per_meter, 4);
	stream.read((char *)&this->y_pixel_per_meter, 4);
	stream.read((char *)&this->color_used, 4);
	stream.read((char *)&this->color_important, 4);
	
	this->bpp = this->bit_count / 8;
	this->line_size = ICEIL(this->bpp * this->width, sizeof(this->line_size)) * sizeof(this->line_size);
	this->image_size = this->line_size * this->height;
	this->binary = (char *)malloc(sizeof(char) * this->image_size);
	stream.read(this->binary, this->image_size);
	stream.close();
}
Exemple #3
0
void t114_init_bad_block_table(build_image_context *context)
{
    u_int32_t bytes_per_entry;
    nvboot_badblock_table *table;
    nvboot_config_table *bct;

    bct = (nvboot_config_table *)(context->bct);

    assert(context != NULL);
    assert(bct != NULL);

    table = &bct->badblock_table;

    bytes_per_entry = ICEIL(context->partition_size,
                            NVBOOT_BAD_BLOCK_TABLE_SIZE);
    table->block_size_log2 = context->block_size_log2;
    table->virtual_blk_size_log2 = NV_MAX(ceil_log2(bytes_per_entry),
                                          table->block_size_log2);
    table->entries_used = iceil_log2(context->partition_size,
                                     table->virtual_blk_size_log2);
}
Exemple #4
0
Image::Image(int width, int height) {
	this->type[0] = 'B';
	this->type[1] = 'M';
	this->reserved1 = 0;
	this->reserved2 = 0;
	this->offset_bits = 54;
	this->header_size = 40;
	this->width = width;
	this->height = height;
	this->planes = 1;
	this->bit_count = 24;
	this->compression = 0;
	this->bpp = this->bit_count / 8;
	this->line_size = ICEIL(this->bpp * this->width, sizeof(this->line_size)) * sizeof(this->line_size);
	this->image_size = this->line_size * this->height;
	this->binary = (char *)malloc(sizeof(char) * this->image_size);
	this->x_pixel_per_meter = 0;
	this->y_pixel_per_meter = 0;
	this->color_used = 0;
	this->color_important = 0;
	this->size = this->offset_bits + this->image_size;
}
static uint32_t pointless_recreate_convert_rec(pointless_recreate_state_t* state, pointless_value_t* v, uint32_t depth)
{
	// in case of cycles, return the previously created create-time handle
	uint32_t handle = UINT32_MAX, child_handle = UINT32_MAX, key_handle = UINT32_MAX, value_handle = UINT32_MAX;

	switch (v->type) {
		case POINTLESS_VECTOR_VALUE:
		case POINTLESS_VECTOR_VALUE_HASHABLE:
		case POINTLESS_VECTOR_I8:
		case POINTLESS_VECTOR_U8:
		case POINTLESS_VECTOR_I16:
		case POINTLESS_VECTOR_U16:
		case POINTLESS_VECTOR_I32:
		case POINTLESS_VECTOR_U32:
		case POINTLESS_VECTOR_I64:
		case POINTLESS_VECTOR_U64:
		case POINTLESS_VECTOR_FLOAT:
			handle = state->vector_r_c_mapping[v->data.data_u32];
			break;
		case POINTLESS_UNICODE_:
		case POINTLESS_STRING_:
			handle = state->string_unicode_r_c_mapping[v->data.data_u32];
			break;
		case POINTLESS_BITVECTOR:
			handle = state->bitvector_r_c_mapping[v->data.data_u32];
			break;
		case POINTLESS_SET_VALUE:
			handle = state->set_r_c_mapping[v->data.data_u32];
			break;
		case POINTLESS_MAP_VALUE_VALUE:
			handle = state->map_r_c_mapping[v->data.data_u32];
			break;
	}

	if (handle != UINT32_MAX)
		return handle;

	handle = POINTLESS_CREATE_VALUE_FAIL;

	uint32_t n_items = 0, i = 0, n_bits = 0;
	pointless_value_t* child_v = 0;
	pointless_value_t* key = 0;
	pointless_value_t* value = 0;
	void* bits = 0;
	void* source_bits = 0;

	if (pointless_is_vector_type(v->type))
		n_items = pointless_reader_vector_n_items(state->p, v);

	switch (v->type) {
		case POINTLESS_VECTOR_VALUE:
		case POINTLESS_VECTOR_VALUE_HASHABLE:
			handle = pointless_create_vector_value(state->c);

			if (handle == POINTLESS_CREATE_VALUE_FAIL) {
				*state->error = "pointless_create_vector_value() failure";
				return POINTLESS_CREATE_VALUE_FAIL;
			}

			state->vector_r_c_mapping[v->data.data_u32] = handle;

			child_v = pointless_reader_vector_value(state->p, v);

			for (i = 0; i < n_items; i++) {
				child_handle = pointless_recreate_convert_rec(state, &child_v[i], depth + 1);

				if (child_handle == POINTLESS_CREATE_VALUE_FAIL)
					return POINTLESS_CREATE_VALUE_FAIL;

				if (pointless_create_vector_value_append(state->c, handle, child_handle) == POINTLESS_CREATE_VALUE_FAIL) {
					*state->error = "pointless_create_vector_value_append() failure";
					return POINTLESS_CREATE_VALUE_FAIL;
				}
			}

			return handle;
		case POINTLESS_VECTOR_I8:
			POINTLESS_RECREATE_FUNC_3(pointless_create_vector_i8_owner, state->c, pointless_reader_vector_i8(state->p, v), n_items);
			state->vector_r_c_mapping[v->data.data_u32] = handle;
			return handle;
		case POINTLESS_VECTOR_U8:
			POINTLESS_RECREATE_FUNC_3(pointless_create_vector_u8_owner, state->c, pointless_reader_vector_u8(state->p, v), n_items);
			state->vector_r_c_mapping[v->data.data_u32] = handle;
			return handle;
		case POINTLESS_VECTOR_I16:
			POINTLESS_RECREATE_FUNC_3(pointless_create_vector_i16_owner, state->c, pointless_reader_vector_i16(state->p, v), n_items);
			state->vector_r_c_mapping[v->data.data_u32] = handle;
			return handle;
		case POINTLESS_VECTOR_U16:
			POINTLESS_RECREATE_FUNC_3(pointless_create_vector_u16_owner, state->c, pointless_reader_vector_u16(state->p, v), n_items);
			state->vector_r_c_mapping[v->data.data_u32] = handle;
			return handle;
		case POINTLESS_VECTOR_I32:
			POINTLESS_RECREATE_FUNC_3(pointless_create_vector_i32_owner, state->c, pointless_reader_vector_i32(state->p, v), n_items);
			state->vector_r_c_mapping[v->data.data_u32] = handle;
			return handle;
		case POINTLESS_VECTOR_U32:
			POINTLESS_RECREATE_FUNC_3(pointless_create_vector_u32_owner, state->c, pointless_reader_vector_u32(state->p, v), n_items);
			state->vector_r_c_mapping[v->data.data_u32] = handle;
			return handle;
		case POINTLESS_VECTOR_I64:
			POINTLESS_RECREATE_FUNC_3(pointless_create_vector_i64_owner, state->c, pointless_reader_vector_i64(state->p, v), n_items);
			state->vector_r_c_mapping[v->data.data_u32] = handle;
			return handle;
		case POINTLESS_VECTOR_U64:
			POINTLESS_RECREATE_FUNC_3(pointless_create_vector_u64_owner, state->c, pointless_reader_vector_u64(state->p, v), n_items);
			state->vector_r_c_mapping[v->data.data_u32] = handle;
			return handle;
		case POINTLESS_VECTOR_FLOAT:
			POINTLESS_RECREATE_FUNC_3(pointless_create_vector_float_owner, state->c, pointless_reader_vector_float(state->p, v), n_items);
			state->vector_r_c_mapping[v->data.data_u32] = handle;
			return handle;
		case POINTLESS_VECTOR_EMPTY:
			POINTLESS_RECREATE_FUNC_1(pointless_create_vector_value, state->c);
			// note: empty vectors don't have any data on the heap, so there is no
			//       need to mark vector_r_c_mapping
			return handle;
		case POINTLESS_UNICODE_:
			POINTLESS_RECREATE_FUNC_2(pointless_create_unicode_ucs4, state->c, pointless_reader_unicode_value_ucs4(state->p, v));
			state->string_unicode_r_c_mapping[v->data.data_u32] = handle;
			if (handle == POINTLESS_CREATE_VALUE_FAIL)
				*state->error = "out of memory";
			return handle;
		case POINTLESS_STRING_:
			POINTLESS_RECREATE_FUNC_2(pointless_create_string_ascii, state->c, pointless_reader_string_value_ascii(state->p, v));
			state->string_unicode_r_c_mapping[v->data.data_u32] = handle;
			if (handle == POINTLESS_CREATE_VALUE_FAIL)
				*state->error = "out of memory";
			return handle;
		case POINTLESS_BITVECTOR_0:
		case POINTLESS_BITVECTOR_1:
		case POINTLESS_BITVECTOR_01:
		case POINTLESS_BITVECTOR_10:
		case POINTLESS_BITVECTOR_PACKED:
			handle = pointless_create_bitvector_compressed(state->c, v);
			if (handle == POINTLESS_CREATE_VALUE_FAIL)
				*state->error = "out of memory";
			return handle;
	
		case POINTLESS_BITVECTOR:
			n_bits = pointless_reader_bitvector_n_bits(state->p, v);
			bits = pointless_calloc(ICEIL(n_bits, 8), 1);

			if (bits == 0) {
				*state->error = "out of memory";
				return POINTLESS_CREATE_VALUE_FAIL;
			}

			source_bits = (void*)((uint32_t*)pointless_reader_bitvector_buffer(state->p, v) + 1);
			memcpy(bits, source_bits, ICEIL(n_bits, 8));

			if (state->normalize_bitvector)
				handle = pointless_create_bitvector(state->c, bits, n_bits);
			else
				handle = pointless_create_bitvector_no_normalize(state->c, bits, n_bits);

			pointless_free(bits);
			bits = 0;

			if (handle == POINTLESS_CREATE_VALUE_FAIL) {
				*state->error = "pointless_create_bitvector() failure";
				return POINTLESS_CREATE_VALUE_FAIL;
			}

			state->bitvector_r_c_mapping[v->data.data_u32] = handle;

			return handle;
		case POINTLESS_SET_VALUE:
			POINTLESS_RECREATE_FUNC_1(pointless_create_set, state->c);
			state->set_r_c_mapping[v->data.data_u32] = handle;

			i = 0;

			while (pointless_reader_set_iter(state->p, v, &key, &i)) {
				key_handle = pointless_recreate_convert_rec(state, key, depth + 1);

				if (key_handle == POINTLESS_CREATE_VALUE_FAIL)
					return POINTLESS_CREATE_VALUE_FAIL;

				if (pointless_create_set_add(state->c, handle, key_handle) == POINTLESS_CREATE_VALUE_FAIL) {
					*state->error = "pointless_create_set_add() failure";
					return POINTLESS_CREATE_VALUE_FAIL;
				}
			}

			return handle;
		case POINTLESS_MAP_VALUE_VALUE:
			POINTLESS_RECREATE_FUNC_1(pointless_create_map, state->c);
			state->map_r_c_mapping[v->data.data_u32] = handle;

			i = 0;

			while (pointless_reader_map_iter(state->p, v, &key, &value, &i)) {
				key_handle = pointless_recreate_convert_rec(state, key, depth + 1);

				if (key_handle == POINTLESS_CREATE_VALUE_FAIL)
					return POINTLESS_CREATE_VALUE_FAIL;

				value_handle = pointless_recreate_convert_rec(state, value, depth + 1);

				if (value_handle == POINTLESS_CREATE_VALUE_FAIL)
					return POINTLESS_CREATE_VALUE_FAIL;

				if (pointless_create_map_add(state->c, handle, key_handle, value_handle) == POINTLESS_CREATE_VALUE_FAIL) {
					*state->error = "pointless_create_map_add() failure";
					return POINTLESS_CREATE_VALUE_FAIL;
				}
			}

			return handle;
		case POINTLESS_EMPTY_SLOT:
			POINTLESS_RECREATE_FUNC_1(pointless_create_empty_slot, state->c);
			return handle;
		case POINTLESS_I32:
			POINTLESS_RECREATE_FUNC_2(pointless_create_i32, state->c, pointless_value_get_i32(v->type, &v->data));
			return handle;
		case POINTLESS_U32:
			POINTLESS_RECREATE_FUNC_2(pointless_create_u32, state->c, pointless_value_get_u32(v->type, &v->data));
			return handle;
		case POINTLESS_FLOAT:
			POINTLESS_RECREATE_FUNC_2(pointless_create_float, state->c, pointless_value_get_float(v->type, &v->data));
			return handle;
		case POINTLESS_BOOLEAN:
			if (pointless_value_get_bool(v->type, &v->data)) {
				POINTLESS_RECREATE_FUNC_1(pointless_create_boolean_true, state->c);
			} else {
				POINTLESS_RECREATE_FUNC_1(pointless_create_boolean_false, state->c);
			}
			return handle;
		case POINTLESS_NULL:
			POINTLESS_RECREATE_FUNC_1(pointless_create_null, state->c);
			return handle;
	}

	*state->error = "unknown type";
	return POINTLESS_CREATE_VALUE_FAIL;
}
Exemple #6
0
ICEILTEMPDECL
#endif

/*
 *        Written by Todd Newman; April. 1987.
 *
 *        Fill a convex polygon.  If the given polygon
 *        is not convex, then the result is undefined.
 *        The algorithm is to order the edges from smallest
 *        y to largest by partitioning the array into a left
 *        edge list and a right edge list.  The algorithm used
 *        to traverse each edge is digital differencing analyzer
 *        line algorithm with y as the major axis. There's some funny linear
 *        interpolation involved because of the subpixel postioning.
 * 
 * count:               number of points
 * ptsIn:               the points
 * xTrans, yTrans:      Translate each point by this
 * xFtrans, yFtrans:    translate before conversion
 *                      by this amount.  This provides
 *                      a mechanism to match rounding
 *                      errors with any shape that must
 *                      meet the polygon exactly.
 */
void miFillSppPoly (PDC pdc, int count, SppPointPtr ptsIn, int xTrans, int yTrans, double xFtrans, double yFtrans)
{
    double          xl = 0, xr = 0, /* x vals of left and right edges */
                    ml = 0,         /* left edge slope */
                    mr = 0,         /* right edge slope */
                    dy,             /* delta y */
                    i;              /* loop counter */
    int             y,              /* current scanline */
                    j,
                    imin,           /* index of vertex with smallest y */
                    ymin,           /* y-extents of polygon */
                    ymax,
                    *Marked;        /* set if this vertex has been used */
    register int    left, right,    /* indices to first endpoints */
                    nextleft,
                    nextright;      /* indices to second endpoints */
    Span            *ptsOut, *FirstPoint;   /* output buffer */

    imin = GetFPolyYBounds(ptsIn, count, yFtrans, &ymin, &ymax);

    y = ymax - ymin + 1;
    if ((count < 3) || (y <= 0))
        return;

    ptsOut = FirstPoint = (Span*)ALLOCATE_LOCAL(sizeof(Span) * y);
    Marked = (int *) ALLOCATE_LOCAL(sizeof(int) * count);

    if(!ptsOut || !Marked)
    {
        if (Marked) DEALLOCATE_LOCAL(Marked);
        if (ptsOut) DEALLOCATE_LOCAL(ptsOut);
        return;
    }

    for(j = 0; j < count; j++)
        Marked[j] = 0;
    nextleft = nextright = imin;
    Marked[imin] = -1;
    y = ICEIL(ptsIn[nextleft].y + yFtrans);

    /*
     *  loop through all edges of the polygon
     */
    do
    {
        /* add a left edge if we need to */
        if ((y > (ptsIn[nextleft].y + yFtrans) ||
              ISEQUAL(y, ptsIn[nextleft].y + yFtrans)) &&
             Marked[nextleft] != 1)
        {
            Marked[nextleft]++;
            left = nextleft++;

            /* find the next edge, considering the end conditions */
            if (nextleft >= count)
                nextleft = 0;

            /* now compute the starting point and slope */
            dy = ptsIn[nextleft].y - ptsIn[left].y;
            if (dy != 0.0)
            { 
                ml = (ptsIn[nextleft].x - ptsIn[left].x) / dy;
                dy = y - (ptsIn[left].y + yFtrans);
                xl = (ptsIn[left].x + xFtrans) + ml * MAX(dy, 0); 
            }
        }

        /* add a right edge if we need to */
        if ((y > ptsIn[nextright].y + yFtrans) ||
              (ISEQUAL(y, ptsIn[nextright].y + yFtrans)
              && Marked[nextright] != 1))
        {
            Marked[nextright]++;
            right = nextright--;

            /* find the next edge, considering the end conditions */
            if (nextright < 0)
                nextright = count - 1;

            /* now compute the starting point and slope */
            dy = ptsIn[nextright].y - ptsIn[right].y;
            if (dy != 0.0) 
            { 
                mr = (ptsIn[nextright].x - ptsIn[right].x) / dy;
                dy = y - (ptsIn[right].y + yFtrans); 
                xr = (ptsIn[right].x + xFtrans) + mr * MAX(dy, 0);
            }
        }


        /*
         *  generate scans to fill while we still have
         *  a right edge as well as a left edge.
         */
        i = (MIN(ptsIn[nextleft].y, ptsIn[nextright].y) + yFtrans) - y;

        if (i < EPSILON)
        {
            if(Marked[nextleft] && Marked[nextright])
            {
                /* Arrgh, we're trapped! (no more points) 
                 * Out, we've got to get out of here before this decadence saps
                 * our will completely! */
                break;
            }
            continue;
        }
        else
        {
                j = (int) i;
                if(!j)
                    j++;
        }
        while (j > 0) 
        {
            int cxl, cxr;

            ptsOut->y = (y) + yTrans;

            cxl = ICEIL(xl);
            cxr = ICEIL(xr);
            /* reverse the edges if necessary */
            if (xl < xr) 
            {
              ptsOut->width = cxr - cxl;
              (ptsOut++)->x = cxl + xTrans;
            }
            else 
            {
              ptsOut->width = cxl - cxr;
              (ptsOut++)->x = cxr + xTrans;
            }
            y++;

            /* increment down the edges */
            xl += ml;
            xr += mr;
            j--;
        }
    }  while (y <= ymax);

    /* Finally, fill the spans we've collected */
    _dc_fill_spans (pdc, FirstPoint, ptsOut-FirstPoint, FALSE);
    DEALLOCATE_LOCAL(Marked);
    DEALLOCATE_LOCAL(FirstPoint);
}
Exemple #7
0
/*
 *	Written by Todd Newman; April. 1987.
 *
 *	Fill a convex polygon.  If the given polygon
 *	is not convex, then the result is undefined.
 *	The algorithm is to order the edges from smallest
 *	y to largest by partitioning the array into a left
 *	edge list and a right edge list.  The algorithm used
 *	to traverse each edge is digital differencing analyzer
 *	line algorithm with y as the major axis. There's some funny linear
 *	interpolation involved because of the subpixel postioning.
 */
void
miFillSppPoly(DrawablePtr dst, GCPtr pgc, int count,    /* number of points */
              SppPointPtr ptsIn,        /* the points */
              int xTrans, int yTrans,   /* Translate each point by this */
              double xFtrans, double yFtrans    /* translate before conversion
                                                   by this amount.  This provides
                                                   a mechanism to match rounding
                                                   errors with any shape that must
                                                   meet the polygon exactly.
                                                 */
    )
{
    double xl = 0.0, xr = 0.0,  /* x vals of left and right edges */
        ml = 0.0,               /* left edge slope */
        mr = 0.0,               /* right edge slope */
        dy,                     /* delta y */
        i;                      /* loop counter */
    int y,                      /* current scanline */
     j, imin,                   /* index of vertex with smallest y */
     ymin,                      /* y-extents of polygon */
     ymax, *width, *FirstWidth, /* output buffer */
    *Marked;                    /* set if this vertex has been used */
    int left, right,            /* indices to first endpoints */
     nextleft, nextright;       /* indices to second endpoints */
    DDXPointPtr ptsOut, FirstPoint;     /* output buffer */

    if (pgc->miTranslate) {
        xTrans += dst->x;
        yTrans += dst->y;
    }

    imin = GetFPolyYBounds(ptsIn, count, yFtrans, &ymin, &ymax);

    y = ymax - ymin + 1;
    if ((count < 3) || (y <= 0))
        return;
    ptsOut = FirstPoint = malloc(sizeof(DDXPointRec) * y);
    width = FirstWidth = malloc(sizeof(int) * y);
    Marked = malloc(sizeof(int) * count);

    if (!ptsOut || !width || !Marked) {
        free(Marked);
        free(width);
        free(ptsOut);
        return;
    }

    for (j = 0; j < count; j++)
        Marked[j] = 0;
    nextleft = nextright = imin;
    Marked[imin] = -1;
    y = ICEIL(ptsIn[nextleft].y + yFtrans);

    /*
     *  loop through all edges of the polygon
     */
    do {
        /* add a left edge if we need to */
        if ((y > (ptsIn[nextleft].y + yFtrans) ||
             ISEQUAL(y, ptsIn[nextleft].y + yFtrans)) &&
            Marked[nextleft] != 1) {
            Marked[nextleft]++;
            left = nextleft++;

            /* find the next edge, considering the end conditions */
            if (nextleft >= count)
                nextleft = 0;

            /* now compute the starting point and slope */
            dy = ptsIn[nextleft].y - ptsIn[left].y;
            if (dy != 0.0) {
                ml = (ptsIn[nextleft].x - ptsIn[left].x) / dy;
                dy = y - (ptsIn[left].y + yFtrans);
                xl = (ptsIn[left].x + xFtrans) + ml * max(dy, 0);
            }
        }

        /* add a right edge if we need to */
        if ((y > ptsIn[nextright].y + yFtrans) ||
            (ISEQUAL(y, ptsIn[nextright].y + yFtrans)
             && Marked[nextright] != 1)) {
            Marked[nextright]++;
            right = nextright--;

            /* find the next edge, considering the end conditions */
            if (nextright < 0)
                nextright = count - 1;

            /* now compute the starting point and slope */
            dy = ptsIn[nextright].y - ptsIn[right].y;
            if (dy != 0.0) {
                mr = (ptsIn[nextright].x - ptsIn[right].x) / dy;
                dy = y - (ptsIn[right].y + yFtrans);
                xr = (ptsIn[right].x + xFtrans) + mr * max(dy, 0);
            }
        }

        /*
         *  generate scans to fill while we still have
         *  a right edge as well as a left edge.
         */
        i = (min(ptsIn[nextleft].y, ptsIn[nextright].y) + yFtrans) - y;

        if (i < EPSILON) {
            if (Marked[nextleft] && Marked[nextright]) {
                /* Arrgh, we're trapped! (no more points) 
                 * Out, we've got to get out of here before this decadence saps
                 * our will completely! */
                break;
            }
            continue;
        }
        else {
            j = (int) i;
            if (!j)
                j++;
        }
        while (j > 0) {
            int cxl, cxr;

            ptsOut->y = (y) + yTrans;

            cxl = ICEIL(xl);
            cxr = ICEIL(xr);
            /* reverse the edges if necessary */
            if (xl < xr) {
                *(width++) = cxr - cxl;
                (ptsOut++)->x = cxl + xTrans;
            }
            else {
                *(width++) = cxl - cxr;
                (ptsOut++)->x = cxr + xTrans;
            }
            y++;

            /* increment down the edges */
            xl += ml;
            xr += mr;
            j--;
        }
    } while (y <= ymax);

    /* Finally, fill the spans we've collected */
    (*pgc->ops->FillSpans) (dst, pgc,
                            ptsOut - FirstPoint, FirstPoint, FirstWidth, 1);
    free(Marked);
    free(FirstWidth);
    free(FirstPoint);
}
static uint32_t pointless_export_py_rec(pointless_export_state_t* state, PyObject* py_object, uint32_t depth)
{
	// don't go too deep
	if (depth >= POINTLESS_MAX_DEPTH) {
		PyErr_SetString(PyExc_ValueError, "structure is too deep");
		state->is_error = 1;
		printf("line: %i\n", __LINE__);
		state->error_line = __LINE__;
		return POINTLESS_CREATE_VALUE_FAIL;
	}

	// check simple types first
	uint32_t handle = POINTLESS_CREATE_VALUE_FAIL;

	// return an error on failure
	#define RETURN_OOM(state) {PyErr_NoMemory(); (state)->is_error = 1; printf("line: %i\n", __LINE__); state->error_line = __LINE__; return POINTLESS_CREATE_VALUE_FAIL;}
	#define RETURN_OOM_IF_FAIL(handle, state) if ((handle) == POINTLESS_CREATE_VALUE_FAIL) RETURN_OOM(state);

	// booleans, need this above integer check, cause PyInt_Check return 1 for booleans
	if (PyBool_Check(py_object)) {
		if (py_object == Py_True)
			handle = pointless_create_boolean_true(&state->c);
		else
			handle = pointless_create_boolean_false(&state->c);

		RETURN_OOM_IF_FAIL(handle, state);
	// integer
	} else if (PyInt_Check(py_object)) {
		long v = PyInt_AS_LONG(py_object);

		// unsigned
		if (v >= 0) {
			if (v > UINT32_MAX) {
				PyErr_Format(PyExc_ValueError, "integer too large for mere 32 bits");
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				state->error_line = __LINE__;
				return POINTLESS_CREATE_VALUE_FAIL;
			}

			handle = pointless_create_u32(&state->c, (uint32_t)v);
		// signed
		} else {
			if (!(INT32_MIN <= v && v <= INT32_MAX)) {
				PyErr_Format(PyExc_ValueError, "integer too large for mere 32 bits with a sign");
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				state->error_line = __LINE__;
				return POINTLESS_CREATE_VALUE_FAIL;
			}

			handle = pointless_create_i32(&state->c, (int32_t)v);
		}

		RETURN_OOM_IF_FAIL(handle, state);
	// long
	} else if (PyLong_Check(py_object)) {
		// this will raise an overflow error if number is outside the legal range of PY_LONG_LONG
		PY_LONG_LONG v = PyLong_AsLongLong(py_object);

		// if there was an exception, clear it, and set our own
		if (PyErr_Occurred()) {
			PyErr_Clear();
			PyErr_SetString(PyExc_ValueError, "value of long is way beyond what we can store right now");
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			state->error_line = __LINE__;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		// unsigned
		if (v >= 0) {
			if (v > UINT32_MAX) {
				PyErr_Format(PyExc_ValueError, "long too large for mere 32 bits");
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				state->error_line = __LINE__;
				return POINTLESS_CREATE_VALUE_FAIL;
			}

			handle = pointless_create_u32(&state->c, (uint32_t)v);
		// signed
		} else {
			if (!(INT32_MIN <= v && v <= INT32_MAX)) {
				PyErr_Format(PyExc_ValueError, "long too large for mere 32 bits with a sign");
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				state->error_line = __LINE__;
				return POINTLESS_CREATE_VALUE_FAIL;
			}

			handle = pointless_create_i32(&state->c, (int32_t)v);
		}

		RETURN_OOM_IF_FAIL(handle, state);
	// None object
	} else if (py_object == Py_None) {
		handle = pointless_create_null(&state->c);
		RETURN_OOM_IF_FAIL(handle, state);
	} else if (PyFloat_Check(py_object)) {
		handle = pointless_create_float(&state->c, (float)PyFloat_AS_DOUBLE(py_object));
		RETURN_OOM_IF_FAIL(handle, state);
	}

	if (handle != POINTLESS_CREATE_VALUE_FAIL)
		return handle;

	// remaining types are containers/big-values, which we track
	// either for space-savings or maintaining circular references

	// if object has been seen before, return its handle
	handle = pointless_export_get_seen(state, py_object);

	if (handle != POINTLESS_CREATE_VALUE_FAIL)
		return handle;

	// list/tuple object
	if (PyList_Check(py_object) || PyTuple_Check(py_object)) {
		// create and cache handle
		assert(is_container(py_object));

		handle = pointless_create_vector_value(&state->c);
		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

		// populate vector
		Py_ssize_t i, n_items = PyList_Check(py_object) ? PyList_GET_SIZE(py_object) : PyTuple_GET_SIZE(py_object);

		for (i = 0; i < n_items; i++) {
			PyObject* child = PyList_Check(py_object) ? PyList_GET_ITEM(py_object, i) : PyTuple_GET_ITEM(py_object, i);
			uint32_t child_handle = pointless_export_py_rec(state, child, depth + 1);

			if (child_handle == POINTLESS_CREATE_VALUE_FAIL)
				return child_handle;

			if (pointless_create_vector_value_append(&state->c, handle, child_handle) == POINTLESS_CREATE_VALUE_FAIL) {
				RETURN_OOM(state);
			}
		}

	// pointless value vectors
	} else if (PyPointlessVector_Check(py_object)) {
		// currently, we only support value vectors, they are simple
		PyPointlessVector* v = (PyPointlessVector*)py_object;
		const char* error = 0;

		switch(v->v->type) {
			case POINTLESS_VECTOR_VALUE:
			case POINTLESS_VECTOR_VALUE_HASHABLE:
				handle = pointless_recreate_value(&v->pp->p, v->v, &state->c, &error);

				if (handle == POINTLESS_CREATE_VALUE_FAIL) {
					printf("line: %i\n", __LINE__);
					state->is_error = 1;
					state->error_line = __LINE__;
					PyErr_Format(PyExc_ValueError, "pointless_recreate_value(): %s", error);
					return POINTLESS_CREATE_VALUE_FAIL;
				}

				break;
			case POINTLESS_VECTOR_I8:
				handle = pointless_create_vector_i8_owner(&state->c, pointless_reader_vector_i8(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_U8:
				handle = pointless_create_vector_u8_owner(&state->c, pointless_reader_vector_u8(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_I16:
				handle = pointless_create_vector_i16_owner(&state->c, pointless_reader_vector_i16(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_U16:
				handle = pointless_create_vector_u16_owner(&state->c, pointless_reader_vector_u16(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_I32:
				handle = pointless_create_vector_i32_owner(&state->c, pointless_reader_vector_i32(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_U32:
				handle = pointless_create_vector_u32_owner(&state->c, pointless_reader_vector_u32(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_I64:
				handle = pointless_create_vector_i64_owner(&state->c, pointless_reader_vector_i64(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_U64:
				handle = pointless_create_vector_u64_owner(&state->c, pointless_reader_vector_u64(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_FLOAT:
				handle = pointless_create_vector_float_owner(&state->c, pointless_reader_vector_float(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_EMPTY:
				handle = pointless_create_vector_value(&state->c);
				break;
			default:
				state->error_line = __LINE__;
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				PyErr_SetString(PyExc_ValueError, "internal error: illegal type for primitive vector");
				return POINTLESS_CREATE_VALUE_FAIL;
		}

		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// python bytearray
	} else if (PyByteArray_Check(py_object)) {
		// create handle and hand over the memory
		Py_ssize_t n_items = PyByteArray_GET_SIZE(py_object);

		if (n_items > UINT32_MAX) {
			PyErr_SetString(PyExc_ValueError, "bytearray has too many items");
			state->error_line = __LINE__;
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		handle = pointless_create_vector_u8_owner(&state->c, (uint8_t*)PyByteArray_AS_STRING(py_object), (uint32_t)n_items);
		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// primitive vectors
	} else if (PyPointlessPrimVector_Check(py_object)) {
		// we just hand over the memory
		PyPointlessPrimVector* prim_vector = (PyPointlessPrimVector*)py_object;
		uint32_t n_items = pointless_dynarray_n_items(&prim_vector->array);
		void* data = prim_vector->array._data;

		switch (prim_vector->type) {
			case POINTLESS_PRIM_VECTOR_TYPE_I8:
				handle = pointless_create_vector_i8_owner(&state->c, (int8_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_U8:
				handle = pointless_create_vector_u8_owner(&state->c, (uint8_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_I16:
				handle = pointless_create_vector_i16_owner(&state->c, (int16_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_U16:
				handle = pointless_create_vector_u16_owner(&state->c, (uint16_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_I32:
				handle = pointless_create_vector_i32_owner(&state->c, (int32_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_U32:
				handle = pointless_create_vector_u32_owner(&state->c, (uint32_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_I64:
				handle = pointless_create_vector_i64_owner(&state->c, (int64_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_U64:
				handle = pointless_create_vector_u64_owner(&state->c, (uint64_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_FLOAT:
				handle = pointless_create_vector_float_owner(&state->c, (float*)data, n_items);
				break;
			default:
				PyErr_SetString(PyExc_ValueError, "internal error: illegal type for primitive vector");
				state->error_line = __LINE__;
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				return POINTLESS_CREATE_VALUE_FAIL;
		}

		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// unicode object
	} else if (PyUnicode_Check(py_object)) {
		// get it from python
		Py_UNICODE* python_buffer = PyUnicode_AS_UNICODE(py_object);

		// string must not contain zero's
		Py_ssize_t s_len_python = PyUnicode_GET_SIZE(py_object);

		#if Py_UNICODE_SIZE == 4
		uint32_t s_len_pointless = pointless_ucs4_len(python_buffer);
		#else
		uint32_t s_len_pointless = pointless_ucs2_len(python_buffer);
		#endif

		if (s_len_python < 0 || (uint64_t)s_len_python != s_len_pointless) {
			PyErr_SetString(PyExc_ValueError, "unicode string contains a zero, where it shouldn't");
			state->error_line = __LINE__;
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		#if Py_UNICODE_SIZE == 4
			if (state->unwiden_strings && pointless_is_ucs4_ascii((uint32_t*)python_buffer))
				handle = pointless_create_string_ucs4(&state->c, python_buffer);
			else
				handle = pointless_create_unicode_ucs4(&state->c, python_buffer);
		#else
			if (state->unwiden_strings && pointless_is_ucs2_ascii(python_buffer))
				handle = pointless_create_string_ucs2(&state->c, python_buffer);
			else
				handle = pointless_create_unicode_ucs2(&state->c, python_buffer);
		#endif

		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// string object
	} else if (PyString_Check(py_object)) {
		// get it from python
		uint8_t* python_buffer = (uint8_t*)PyString_AS_STRING(py_object);

		// string must not contain zero's
		Py_ssize_t s_len_python = PyString_GET_SIZE(py_object);
		uint32_t s_len_pointless = pointless_ascii_len(python_buffer);

		if (s_len_python < 0 || (uint64_t)s_len_python != s_len_pointless) {
			PyErr_SetString(PyExc_ValueError, "string contains a zero, where it shouldn't");
			state->error_line = __LINE__;
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		handle = pointless_create_string_ascii(&state->c, python_buffer);
		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// dict object
	} else if (PyDict_Check(py_object)) {
		handle = pointless_create_map(&state->c);
		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

		PyObject* key = 0;
		PyObject* value = 0;
		Py_ssize_t pos = 0;

		while (PyDict_Next(py_object, &pos, &key, &value)) {
			uint32_t key_handle = pointless_export_py_rec(state, key, depth + 1);
			uint32_t value_handle = pointless_export_py_rec(state, value, depth + 1);

			if (key_handle == POINTLESS_CREATE_VALUE_FAIL || value_handle == POINTLESS_CREATE_VALUE_FAIL)
				break;

			if (pointless_create_map_add(&state->c, handle, key_handle, value_handle) == POINTLESS_CREATE_VALUE_FAIL) {
				PyErr_SetString(PyExc_ValueError, "error adding key/value pair to map");
				state->error_line = __LINE__;
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				break;
			}
		}

		if (state->is_error) {
			return POINTLESS_CREATE_VALUE_FAIL;
		}

	// set object
	} else if (PyAnySet_Check(py_object)) {
		PyObject* iterator = PyObject_GetIter(py_object);
		PyObject* item = 0;

		if (iterator == 0) {
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			state->error_line = __LINE__;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		// get a handle
		handle = pointless_create_set(&state->c);
		RETURN_OOM_IF_FAIL(handle, state);

		// cache object
		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

		// iterate over it
		while ((item = PyIter_Next(iterator)) != 0) {
			uint32_t item_handle = pointless_export_py_rec(state, item, depth + 1);

			if (item_handle == POINTLESS_CREATE_VALUE_FAIL)
				break;

			if (pointless_create_set_add(&state->c, handle, item_handle) == POINTLESS_CREATE_VALUE_FAIL) {
				PyErr_SetString(PyExc_ValueError, "error adding item to set");
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				state->error_line = __LINE__;
				break;
			}
		}

		Py_DECREF(iterator);

		if (PyErr_Occurred()) {
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			state->error_line = __LINE__;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

	// bitvector
	} else if (PyPointlessBitvector_Check(py_object)) {
		PyPointlessBitvector* bitvector = (PyPointlessBitvector*)py_object;

		if (bitvector->is_pointless) {
			uint32_t i, n_bits = pointless_reader_bitvector_n_bits(&bitvector->pointless_pp->p, bitvector->pointless_v);
			void* bits = pointless_calloc(ICEIL(n_bits, 8), 1);

			if (bits == 0) {
				RETURN_OOM(state);
			}

			for (i = 0; i < n_bits; i++) {
				if (pointless_reader_bitvector_is_set(&bitvector->pointless_pp->p, bitvector->pointless_v, i))
					bm_set_(bits, i);
			}

			if (state->normalize_bitvector)
				handle = pointless_create_bitvector(&state->c, bits, n_bits);
			else
				handle = pointless_create_bitvector_no_normalize(&state->c, bits, n_bits);
			pointless_free(bits);
			bits = 0;

		} else {
			if (state->normalize_bitvector)
				handle = pointless_create_bitvector(&state->c, bitvector->primitive_bits, bitvector->primitive_n_bits);
			else
				handle = pointless_create_bitvector_no_normalize(&state->c, bitvector->primitive_bits, bitvector->primitive_n_bits);
		}

		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	} else if (PyPointlessSet_Check(py_object)) {
		PyPointlessSet* set = (PyPointlessSet*)py_object;
		const char* error = 0;
		handle = pointless_recreate_value(&set->pp->p, set->v, &state->c, &error);

		if (handle == POINTLESS_CREATE_VALUE_FAIL) {
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			state->error_line = __LINE__;
			PyErr_Format(PyExc_ValueError, "pointless_recreate_value(): %s", error);
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	} else if (PyPointlessMap_Check(py_object)) {
		PyPointlessMap* map = (PyPointlessMap*)py_object;
		const char* error = 0;
		handle = pointless_recreate_value(&map->pp->p, map->v, &state->c, &error);

		if (handle == POINTLESS_CREATE_VALUE_FAIL) {
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			state->error_line = __LINE__;
			PyErr_Format(PyExc_ValueError, "pointless_recreate_value(): %s", error);
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// type not supported
	} else {
		PyErr_Format(PyExc_ValueError, "type <%s> not supported", py_object->ob_type->tp_name);
		state->error_line = __LINE__;
		printf("line: %i\n", __LINE__);
		state->is_error = 1;
	}

	#undef RETURN_OOM
	#undef RETURN_IF_OOM

	return handle;
}
Exemple #9
0
int blipTriFn2(ppf vX, ppf vY, flt *A, flt *F)   /* F = f(A) */
{
regflt	ss,tt;
flt     x1  = A[0],  y1 = A[1];	/* A = [Ax,Ay], 2x3 matrix of xy row vectors*/
flt     x2  = A[2],  y2 = A[3];	/* Expecting y1 <= y2 & y3 and the angle  */
flt     x3  = A[4],  y3 = A[5]; /* from side12 to side23 > 0 */
flt 	g1  = F[0],  h1 = F[1];	/* F = f(A) = [g(Ax),h(Ay)] */
flt 	g2  = F[2],  h2 = F[3];	/* ie: F[1] = g(Ax1), F[2] = h(Ax2) */
flt 	g3  = F[4],  h3 = F[5];
flt	g21 = (g2 - g1), g31 = (g3 - g1), g32 = (g3 - g2);
flt	h21 = (h2 - h1), h31 = (h3 - h1), h32 = (h3 - h2);
flt 	x21 = (x2 - x1), x31 = (x3 - x1), x32 = (x3 - x2);
flt 	xL, xR, gL,hL, gR,hR, gRL,hRL;
flt	yM, s21, s31, s32, **pX, **pY, *fX,*fY;
int 	j,jI,jM,jF, k,kL,kR, y2_gt_y3=0;

  if ((x2-x1)*(y3-y1) - (x3-x1)*(y2-y1) < 0) {
    die("blipTriFn2: neg oriented triangle...");
  }
  assert(y1  <=  y2);
  assert(y1  <=  y3);

  jI = ICEIL(y1);	/* Ensure (ss >= 0);  was: jI = IRINTF(y1); */
  if (y2 <= y3)  jM = IRINTF(y2), jF = IRINTF(y3), yM = y2;
  else           jM = IRINTF(y3), jF = IRINTF(y2), yM = y3, y2_gt_y3 = 1;

  if (jI < jM) {	/* implies s21 & s31 won't blow up */
    s21  = 1.0F/(y2 - y1);
    s31  = 1.0F/(y3 - y1);
    for (j = jI, pX = &vX[j], pY = &vY[j]; j <= jM; j++) {
      ss   = (j - y1);
      tt   = ss * s31;
      hL   = h1 + h31*tt;
      gL   = g1 + g31*tt;
      xL   = x1 + x31*tt;
      tt   = ss * s21;
      hR   = h1 + h21*tt;
      gR   = g1 + g21*tt;
      xR   = x1 + x21*tt;
      kL   = IRINTF(xL);  kR = IRINTF(xR);    /* Later: switch if x3 < x2 */
      if (kL < kR) {
        gRL  = (gR - gL);
        hRL  = (hR - hL);
        ss   = 1.0F/(kR - kL);
        for (tt=0.0F, k=kL, fX= *pX++ + kL, fY= *pY++ + kL; k <= kR; tt+=ss, k++)  {
          *fX++  =  gL + gRL*tt;
          *fY++  =  hL + hRL*tt;
        }
      }
      else if (kL == kR) {
        (*pX++)[kL]  =  (gL + gR)*0.5F;
        (*pY++)[kL]  =  (hL + hR)*0.5F;
      }
      else {
        pX++, pY++; warn("iTB UPPER: kL:%d > kR:%d at j:%d",kL,kR,j);
      }
    }
  }
#if 0		/* @@ commented out by sprax, Jan 2, 1995 */
  else --jM;	/* Compensate for j about to be initialized to jM+1 */
#endif

/** warn("blipTriFn2: Now for lower triangle! -- jM,jF: %d %d",jM,jF); **/
/** if (y3 < y2) then side12 continues as L, but side32 replaces side13 **/
/** if (y2 < y3) then side13 continues as R, but side23 replaces side12 **/

  if (jM < jF) {	/* Implies y2 != y3, so s32 won't blow up. */
    s32  = 1.0F/(y3 - y2);
    if (y2_gt_y3) {	/* side12 continues as R, side32 replaces side13 as L */

      s21  = 1.0F/(y2 - y1);

      for (jI=jM+1, j = jI, pX = &vX[j], pY = &vY[j]; j <= jF; j++) {

        tt   =     - s32*(j - yM);	/* NB: y3 < y2, so s32 < 0 */
        hL   =  h3 - h32*tt;
        gL   =  g3 - g32*tt;
        xL   =  x3 - x32*tt;

        tt   =       s21*(j - y1);
        hR   =  h1 + h21*tt;
        gR   =  g1 + g21*tt;
        xR   =  x1 + x21*tt;

        kL   = IRINTF(xL);  kR = IRINTF(xR);    /* Later: switch if x3 < x2 */
        if (kL < kR) {
          gRL  = (gR - gL);
          hRL  = (hR - hL);
          ss   = 1.0F/(kR - kL);
          for (tt=0.0F, k=kL, fX= *pX++ + kL, fY= *pY++ + kL; k <= kR; tt+=ss, k++)  {
            *fX++  =  gL + gRL*tt;
            *fY++  =  hL + hRL*tt;
          }
        }
/**************************************** @@ beg temporary test ***************/
        else if (kL == kR) {
          (*pX++)[kL]  =  (gL + gR)*0.5F;
          (*pY++)[kL]  =  (hL + hR)*0.5F;
        }
        else {
          pX++, pY++; warn("iTB LOWER y2 > y3: kL:%d > kR:%d at j:%d",kL,kR,j);
        }
/**************************************** @@ end temporary test ***************/
      }
    }
    else {  /* (! y2_gt_y3), so side13 continues as L, side23 replaces side 12 as R */

      s31  = 1.0F/(y3 - y1);

      for (jI=jM+1, j = jI, pX = &vX[j], pY = &vY[j]; j <= jF; j++) {

        tt   =       s31*(j - y1);
        hL   =  h1 + h31*tt;
        gL   =  g1 + g31*tt;
        xL   =  x1 + x31*tt;

        tt   =       s32*(j - yM);
        hR   =  h2 + h32*tt;
        gR   =  g2 + g32*tt;
        xR   =  x2 + x32*tt;

        kL   = IRINTF(xL);
        kR   = ICEIL(xR);    /* was: IRINTF(xR);  Later: switch if x3 < x2 */
        if (kL < kR) {
          gRL  = (gR - gL);
          hRL  = (hR - hL);
          ss   = 1.0F/(kR - kL);
          for (tt=0.0F, k=kL, fX= *pX++ + kL, fY= *pY++ + kL; k <= kR; tt+=ss, k++)  {
            *fX++  =  gL + gRL*tt;
            *fY++  =  hL + hRL*tt;
          }
        }
/**************************************** @@ beg temporary test ***************/
        else if (kL == kR) {
          (*pX++)[kL]  =  (gL + gR)*0.5F;
          (*pY++)[kL]  =  (hL + hR)*0.5F;
        }
        else {
          pX++, pY++; warn("iTB LOWER y2 <= y3: kL:%d > kR:%d at j:%d",kL,kR,j);
          /*assert(kL < kR);*/
        }
/**************************************** @@ end temporary test ***************/
      }
    }
  }
return 1;
}