mlib_status
__mlib_ImageFilteredSubsample(
    ARGS)
{
	mlib_type type;
	mlib_d64 fhkernel[16], fvkernel[16];
	mlib_s32 kw = 2 * hSize - hParity;
	mlib_s32 kh = 2 * vSize - vParity;
	mlib_s32 i, j, iscale;
	mlib_d64 sum_p, sum_n, sum;

	MLIB_IMAGE_CHECK(dst);
	MLIB_IMAGE_CHECK(src);
	MLIB_IMAGE_TYPE_EQUAL(dst, src);
	MLIB_IMAGE_CHAN_EQUAL(dst, src);

	if (edge != MLIB_EDGE_DST_NO_WRITE)
		return (MLIB_FAILURE);

	type = mlib_ImageGetType(dst);

/* MMX version */
	if (type == MLIB_BYTE) {
		for (i = 0; i < hSize; i++) {
			fhkernel[i] = fhkernel[kw - 1 - i] =
			    hKernel[hSize - 1 - i];
		}
		for (i = 0; i < vSize; i++) {
			fvkernel[i] = fvkernel[kh - 1 - i] =
			    vKernel[vSize - 1 - i];
		}

		sum_p = 0;
		sum_n = 0;
		for (j = 0; j < kh; j++) {
			for (i = 0; i < kw; i++) {
				mlib_d64 kk = fvkernel[j] * fhkernel[i];

				if (kk > 0)
					sum_p += kk;
				else
					sum_n -= kk;
			}
		}
		sum = (sum_p > sum_n) ? sum_p : sum_n;
		iscale = 1 + mlib_ilogb((128.0 / 127.) * sum);
		if (iscale < 0)
			iscale = 0;
		if (iscale < 7)
			return (mlib_m_ImageFilteredSubsample_8nw_1(
			    PARAMS_MMX));
	}

	if (kh > 2 * scaleY || (kh == 2 * scaleY && scaleY > 1)) {
		switch (type) {
		case MLIB_BYTE:
			return (mlib_ImageFilteredSubsample_8nw_2(PARAMS));
		case MLIB_SHORT:
			return (mlib_ImageFilteredSubsample_16nw_2(PARAMS));
		case MLIB_USHORT:
			return (mlib_ImageFilteredSubsample_u16nw_2(PARAMS));
		case MLIB_INT:
			return (mlib_ImageFilteredSubsample_32nw_2(PARAMS));
		default:
			return (MLIB_FAILURE);
		}
	} else {
		switch (type) {
		case MLIB_BYTE:
			return (mlib_ImageFilteredSubsample_8nw_1(PARAMS));
		case MLIB_SHORT:
			return (mlib_ImageFilteredSubsample_16nw_1(PARAMS));
		case MLIB_USHORT:
			return (mlib_ImageFilteredSubsample_u16nw_1(PARAMS));
		case MLIB_INT:
			return (mlib_ImageFilteredSubsample_32nw_1(PARAMS));
		default:
			return (MLIB_FAILURE);
		}
	}
}
Esempio n. 2
0
mlib_status
mlib_ImageGridWarpTable_alltypes(
    mlib_image *dst,
    const mlib_image *src,
    const mlib_f32 *xWarpPos,
    const mlib_f32 *yWarpPos,
    mlib_d64 postShiftX,
    mlib_d64 postShiftY,
    mlib_s32 xStart,
    mlib_s32 xStep,
    mlib_s32 xNumCells,
    mlib_s32 yStart,
    mlib_s32 yStep,
    mlib_s32 yNumCells,
    const void *table,
    mlib_edge edge)
{
	mlib_type type;
	mlib_u8 *srcLinePtr, *srcData, *dstData;
	mlib_s32 srcWidth, dstWidth, srcHeight, dstHeight;
	mlib_s32 srcStride, dstStride, nchan;
	mlib_s32 *leftEdges, *rightEdges, *xStarts, *yStarts, *sides;
	mlib_affine_workspace ws[1];
	mlib_d64 buff_local[BUFF_SIZE / sizeof (mlib_d64)];
	void *buffer = buff_local;
	const mlib_u8 **lineAddr;
	mlib_u8 *pbuff;
	mlib_s32 kw, kh, kw1, kh1, kw2, kh2, bsize, bsize0, bsize1;
	mlib_status status;
	fun_type_nw fun_nw = NULL;
	mlib_interp_table *tbl = (mlib_interp_table *) table;
	mlib_u8 *paddings;
	mlib_s32 i, x_shift, y_shift;
	mlib_s32 xFirst, xLast, xSkip, xRest;
	mlib_s32 yFirst, yLast, ySkip, yRest;
	mlib_s32 elt_size = 1;
	mlib_d64 minX, minY, maxX, maxY;
	mlib_d64 dx_shift, dy_shift;
	mlib_s32 xBeg, xEnd;
	mlib_s32 yBeg, yEnd;
	mlib_s32 yskip, xskip, yrest, xrest;
	mlib_s32 x, y, cx, cy;
	mlib_d64 px0, py0, px1, py1, px3, py3;
	mlib_d64 dx0, dx1, dy0, dy1, cx0, cx1, cy0, cy1, dx, dy, cx2, cy2, cx3,
	    cy3;
	mlib_d64 delta_x, delta_y;
	mlib_d64 xs, ys;
	mlib_d64 xNum, yNum;
	mlib_d64 xStep1 = 1.0 / xStep, yStep1 = 1.0 / yStep;
	mlib_s32 is_clip, is_clip1, is_clip2, is_clip3, is_clip4;
	mlib_d64 tE, tL, tmp_x0, tmp_y0, tmp_dx, tmp_dy, num, denom, t;
	mlib_d64 d_rdx, d_rdy, x0, y0, x1, y1;
	mlib_s32 shift_left, shift_right, max_xsize;

/* check for obvious errors */
	MLIB_IMAGE_CHECK(src);
	MLIB_IMAGE_CHECK(dst);
	MLIB_IMAGE_TYPE_EQUAL(src, dst);
	MLIB_IMAGE_CHAN_EQUAL(src, dst);

	MLIB_IMAGE_GET_ALL_PARAMS(src, type, nchan, srcWidth, srcHeight,
	    srcStride, srcData);
	MLIB_IMAGE_GET_ALL_PARAMS(dst, type, nchan, dstWidth, dstHeight,
	    dstStride, dstData);
	paddings = mlib_ImageGetPaddings(src);

	if (srcWidth >= (1 << 15) || srcHeight >= (1 << 15)) {
		return (MLIB_FAILURE);
	}

	for (xFirst = 0; ; xFirst++) {
		if ((xStart + xFirst * xStep + xStep - 1) >= 0)
			break;
	}

	for (yFirst = 0; ; yFirst++) {
		if ((yStart + yFirst * yStep + yStep - 1) >= 0)
			break;
	}

	for (xLast = xNumCells - 1; xLast >= xFirst; xLast--) {
		if ((xStart + xLast * xStep) <= (dstWidth - 1))
			break;
	}

	for (yLast = yNumCells - 1; yLast >= yFirst; yLast--) {
		if ((yStart + yLast * yStep) <= (dstHeight - 1))
			break;
	}

	if ((xStart + xFirst * xStep) < 0)
		xSkip = -(xStart + xFirst * xStep);
	else
		xSkip = 0;

	if ((yStart + yFirst * yStep) < 0)
		ySkip = -(yStart + yFirst * yStep);
	else
		ySkip = 0;

	if ((xStart + xLast * xStep + xStep) > (dstWidth))
		xRest = (xStart + xLast * xStep + xStep) - (dstWidth);
	else
		xRest = 0;

	if ((yStart + yLast * yStep + yStep) > (dstHeight))
		yRest = (yStart + yLast * yStep + yStep) - (dstHeight);
	else
		yRest = 0;

	kw = tbl->width;
	kh = tbl->height;
	kw1 = tbl->leftPadding;
	kh1 = tbl->topPadding;
	kw2 = kw - kw1 - 1;
	kh2 = kh - kh1 - 1;

	x_shift = INT_BITS - mlib_ilogb(srcWidth + kw);
	y_shift = INT_BITS - mlib_ilogb(srcHeight + kh);

	dx_shift = (mlib_d64)(1 << x_shift);
	dy_shift = (mlib_d64)(1 << y_shift);

	if (type == MLIB_BYTE)
		elt_size = 1;
	else if (type == MLIB_SHORT)
		elt_size = 2;
	else if (type == MLIB_INT)
		elt_size = 3;
	else if (type == MLIB_FLOAT)
		elt_size = 4;
	else if (type == MLIB_DOUBLE)
		elt_size = 5;
	else if (type == MLIB_USHORT)
		elt_size = 0;

	ws->type = elt_size;
	ws->srcData = srcData;
	ws->dstData = dstData;
	ws->srcWidth = srcWidth;
	ws->srcHeight = srcHeight;
	ws->srcStride = srcStride;
	ws->dstStride = dstStride;
	ws->nchan = nchan;
	ws->x_shift0 = x_shift;
	ws->y_shift = y_shift;
	ws->x_move = (kw1 << x_shift);
	ws->y_move = (kh1 << y_shift);
	ws->affine_mask = 1;

	if (!elt_size)
		elt_size = 6;
/* VIS version of non NULL */
	fun_nw = mlib_ImageAffine_GetFunc(ws, tbl);

	if (fun_nw == NULL)
/* for U8 via F32 */
		fun_nw = mlib_ImageAffine_ConvertImage(src, ws, tbl);

	if (fun_nw == NULL) {
		if (nchan == 3) {
			fun_nw = fun_array_nw[2 * elt_size - 1];
		} else {
			fun_nw = fun_array_nw[2 * elt_size - 2];
		}
	}

	bsize0 = (srcHeight * sizeof (mlib_u8 *) + 7) & ~7;
	bsize1 = 6 * dstHeight * sizeof (mlib_s32) + 8;

	bsize = bsize0 + bsize1;

	if (bsize > BUFF_SIZE) {
		buffer = __mlib_malloc(bsize);

		if (buffer == NULL)
			return (MLIB_FAILURE);
	}

	pbuff = buffer;
	lineAddr = (mlib_u8 const **)pbuff;
	pbuff += bsize0;

	srcLinePtr = (mlib_u8 *)(ws->srcData);
	srcStride = ws->srcStride;
	for (i = 0; i < srcHeight; i++) {
		lineAddr[i] = srcLinePtr;
		srcLinePtr += srcStride;
	}

	leftEdges = (mlib_s32 *)pbuff;
	rightEdges = (mlib_s32 *)pbuff + dstHeight;
	xStarts = (mlib_s32 *)pbuff + 2 * dstHeight;
	yStarts = (mlib_s32 *)pbuff + 3 * dstHeight;
	sides = (mlib_s32 *)pbuff + 4 * dstHeight;

	ws->sides = sides;

	minX = kw1 + 0.5;
	minY = kh1 + 0.5;
	maxX = srcWidth - kw2 + 0.5;
	maxY = srcHeight - kh2 + 0.5;

	if (edge == MLIB_EDGE_SRC_PADDED) {
		if (minX < paddings[0])
			minX = paddings[0];

		if (minY < paddings[1])
			minY = paddings[1];

		if (maxX > (srcWidth - paddings[2]))
			maxX = srcWidth - paddings[2];

		if (maxY > (srcHeight - paddings[3]))
			maxY = srcHeight - paddings[3];
	}

	if ((minX >= maxX) || (minY >= maxY)) {

		if (ws->srcData != srcData)
			__mlib_free(ws->srcData);

		if (buffer != (mlib_s32 *)buff_local)
			__mlib_free(buffer);
		return (MLIB_SUCCESS);
	}

	for (y = yFirst, cy = yStart + yFirst * yStep; y <= yLast;
	    y++, cy += yStep) {
		yskip = (y == yFirst) ? ySkip : 0;
		yrest = (y == yLast) ? yRest : 0;
		yBeg = cy + yskip;
		yEnd = cy + (yStep - 1) - yrest;
		yNum = yEnd - yBeg;
		ys = yskip + 0.5;
		INIT_GRID_ROW(xFirst, y);
		for (x = xFirst, cx = xStart + xFirst * xStep; x <= xLast;
		    x++, cx += xStep) {
			xskip = (x == xFirst) ? xSkip : 0;
			xrest = (x == xLast) ? xRest : 0;
			xBeg = cx + xskip;
			xEnd = cx + (xStep - 1) - xrest;
			xNum = xEnd - xBeg;
			xs = xskip + 0.5;
			INCR_GRID_ROW(x, y, xs, ys);

			ws->yStart = yBeg;
			ws->yFinish = yEnd;

			max_xsize = 0;

			if (IS_CELL_CLIP()) {

				for (i = yBeg; i <= yEnd; i++) {
					tE = 0;
					tL = xNum;
					tmp_x0 = cx0 + (i - yBeg) * dx0;
					tmp_y0 = cy0 + (i - yBeg) * dy0;
					tmp_dx = dx + (i - yBeg) * delta_x;
					tmp_dy = dy + (i - yBeg) * delta_y;

					if (tmp_dx) {
						d_rdx = 1.0 / tmp_dx;
						MLIB_CLIP(d_rdx,
						    -tmp_x0 + minX);
						MLIB_CLIP(-d_rdx,
						    tmp_x0 - maxX);
					} else if ((tmp_x0 < minX) ||
					    (tmp_x0 >= maxX)) {
						leftEdges[i] = 1;
						rightEdges[i] = 0;
						continue;
					}

					if (tmp_dy) {
						d_rdy = 1.0 / tmp_dy;
						MLIB_CLIP(d_rdy,
						    -tmp_y0 + minY);
						MLIB_CLIP(-d_rdy,
						    tmp_y0 - maxY);
					} else if ((tmp_y0 < minY) ||
					    (tmp_y0 >= maxY)) {
						leftEdges[i] = 1;
						rightEdges[i] = 0;
						continue;
					}

					if (tE > tL) {
						leftEdges[i] = 1;
						rightEdges[i] = 0;
						continue;
					}

					shift_left = (mlib_s32)tE;

					if ((mlib_d64)shift_left != tE)
						shift_left++;
					shift_right = (mlib_s32)tL;

					if ((mlib_d64)shift_right != tL)
						shift_right++;

					x0 = tmp_x0 + shift_left * tmp_dx;
					x1 = tmp_x0 + shift_right * tmp_dx;

					if (tmp_dx >= 0) {
						if (x0 < minX)
							shift_left++;

						if (x1 >= maxX)
							shift_right--;
					} else {

						if (x0 >= maxX)
							shift_left++;

						if (x1 < minX)
							shift_right--;
					}

					y0 = tmp_y0 + shift_left * tmp_dy;
					y1 = tmp_y0 + shift_right * tmp_dy;

					if (tmp_dy >= 0) {
						if (y0 < minY)
							shift_left++;

						if (y1 >= maxY)
							shift_right--;
					} else {

						if (y0 >= maxY)
							shift_left++;

						if (y1 < minY)
							shift_right--;
					}

					x0 = tmp_x0 + shift_left * tmp_dx;
					y0 = tmp_y0 + shift_left * tmp_dy;

					leftEdges[i] = xBeg + shift_left;
					rightEdges[i] = xBeg + shift_right;

					if ((shift_right - shift_left + 1) >
					    max_xsize)
						max_xsize =
						    (shift_right - shift_left +
						    1);

					xStarts[i] =
					    (mlib_s32)((x0 - 0.5) * dx_shift);
					yStarts[i] =
					    (mlib_s32)((y0 - 0.5) * dy_shift);
					sides[i * 2 + 2] =
					    (mlib_s32)(tmp_dx * dx_shift);
					sides[i * 2 + 3] =
					    (mlib_s32)(tmp_dy * dy_shift);
				}
			} else {

				if ((xEnd - xBeg + 1) > max_xsize)
					max_xsize = (xEnd - xBeg + 1);

#ifdef __SUNPRO_C
#pragma pipeloop(0)
#endif /* __SUNPRO_C */
				for (i = yBeg; i <= yEnd; i++) {
					tmp_x0 = cx0 + (i - yBeg) * dx0;
					tmp_y0 = cy0 + (i - yBeg) * dy0;
					tmp_dx = dx + (i - yBeg) * delta_x;
					tmp_dy = dy + (i - yBeg) * delta_y;

					leftEdges[i] = xBeg;
					rightEdges[i] = xEnd;
					xStarts[i] =
					    (mlib_s32)((tmp_x0 -
					    0.5) * dx_shift);
					yStarts[i] =
					    (mlib_s32)((tmp_y0 -
					    0.5) * dy_shift);
					sides[i * 2 + 2] =
					    (mlib_s32)(tmp_dx * dx_shift);
					sides[i * 2 + 3] =
					    (mlib_s32)(tmp_dy * dy_shift);
				}
			}

			if (max_xsize > 0) {
				ws->max_xsize = max_xsize;
				status =
				    fun_nw(dstData + (yBeg - 1) * dstStride,
				    lineAddr, leftEdges, rightEdges, xStarts,
				    yStarts, ws, tbl);

				if (status != MLIB_SUCCESS) {
					if (ws->srcData != srcData)
						__mlib_free(ws->srcData);

					if (buffer != (mlib_s32 *)buff_local)
						__mlib_free(buffer);
					return (MLIB_FAILURE);
				}
			}
		}
	}

	if (ws->srcData != srcData)
		__mlib_free(ws->srcData);

	if (buffer != (mlib_s32 *)buff_local)
		__mlib_free(buffer);

	return (MLIB_SUCCESS);
}
mlib_status FUNC(
    MxN) (
    mlib_image *dst,
    const mlib_image *src,
    const mlib_s32 *kernel,
    mlib_s32 m,
    mlib_s32 n,
    mlib_s32 dm,
    mlib_s32 dn,
    mlib_s32 scale,
    const void *colormap)
{
	mlib_type stype, dtype;
	mlib_u8 *sl, *dl;
	mlib_u8 *lut_table;
	mlib_s32 offset, off, kw, dn1;
	mlib_s32 schan, dchan, sll, dll, sw, sh, dw, dh;
	mlib_s32 row, i, j, bsize, buff_ind = 0, func_ind, method;
	mlib_u16 *pbuff, *buff_lcl[2 * MAX_N], **buff_arr = buff_lcl, **buff;
	mlib_d64 *buffd;
	mlib_d64 kern_lcl[MAX_N * MAX_M], *kern = kern_lcl, *pkern;
	mlib_d64 dscale;
	func_dm_type func_dm;

	mlib_s32 vis_scale, kern_i;
	mlib_s32 kern_size, isum;
	mlib_d64 sum, norm;
	mlib_f32 fscale;
	mlib_s32 bit_offset;
	mlib_u8 *buff_dst;

	MLIB_IMAGE_GET_ALL_PARAMS(dst, dtype, dchan, dw, dh, dll, dl);
	MLIB_IMAGE_GET_ALL_PARAMS(src, stype, schan, sw, sh, sll, sl);
	bit_offset = mlib_ImageGetBitOffset(dst);

	if (!(stype == MLIB_BYTE && schan == 1)) {
		return (MLIB_FAILURE);
	}
#if 0
	for (i = 0; i <= m * dn + dm; i++) {
		if (kernel[i])
			return (MLIB_FAILURE);
	}

#endif /* 0 */

	dn = n - 1 - dn;
	dm = m - 1 - dm;
	kern_size = m * dn + dm;

	if (n > MAX_N || m > MAX_M) {
		kern =
		    __mlib_malloc(n * m * sizeof (mlib_d64) +
		    2 * n * sizeof (mlib_u16 *));

		if (kern == NULL)
			return (MLIB_FAILURE);
		buff_arr = (mlib_u16 **)(kern + n * m);
	}

	dscale = 1.0;
	while (scale > 30) {
		dscale *= 1.0 / (1 << 30);
		scale -= 30;
	}

	dscale /= (1 << scale);

/* load kernel */
	kernel += m * n - 1;
	sum = 0;
	for (i = 0; i < kern_size; i++) {
		kern[i] = dscale * kernel[-i];
		sum += mlib_fabs(kern[i]);
	}

	vis_scale = mlib_ilogb(sum);

	if (vis_scale > 13)
		return (MLIB_OUTOFRANGE);
	vis_scale = 14 - vis_scale;

	if (vis_scale > 15)
		vis_scale = 15;
	norm = 32768 >> (15 - vis_scale);
	isum = 0;
	for (i = 0; i < kern_size; i++) {
		if (kern[i] > 0.0) {
			kern_i = (mlib_s32)(kern[i] * norm + 0.5);
		} else {
			kern_i = (mlib_s32)(kern[i] * norm - 0.5);
		}

		isum += abs(kern_i);
		kern[i] = vis_to_double_dup((kern_i << 16) | (kern_i & 0xffff));
	}

/* recalc without rounding */
	if (isum > 32767) {
		dscale *= norm;
		for (i = 0; i < kern_size; i++) {
			kern_i = (mlib_s32)(dscale * kernel[-i]);
			kern[i] =
			    vis_to_double_dup((kern_i << 16) | (kern_i &
			    0xffff));
		}
	}

	fscale = vis_to_float(1 << (vis_scale - 1));
	vis_write_gsr(((16 - vis_scale) << 3) + 2);

	offset = mlib_ImageGetLutOffset(colormap);
	lut_table = (mlib_u8 *)mlib_ImageGetLutInversTable(colormap);

	bsize = (sw + m) * NCHAN;
	bsize = (bsize + 7) & ~7;
	dn1 = (dn) ? dn : 1;
	pbuff =
	    __mlib_malloc((dn1 + 1) * bsize * sizeof (mlib_u16) + EXTRA_BUFF);

	if (pbuff == NULL) {
		if (kern != kern_lcl)
			__mlib_free(kern);
		return (MLIB_FAILURE);
	}

	for (j = 0; j < dn1; j++) {
		buff_arr[dn1 + j] = buff_arr[j] = pbuff + j * bsize;
	}

	buff_ind = 0;
	buffd = (mlib_d64 *)(pbuff + dn1 * bsize);
	buff_dst = (mlib_u8 *)((mlib_u16 *)buffd + bsize);

/* clear buffer */
	for (i = 0; i < dn * (bsize / 4); i++) {
		((mlib_d64 *)pbuff)[i] = 0;
	}

	func_ind = dm;

	if (func_ind > KH_MAX)
		func_ind = KH_MAX;
	method = mlib_ImageGetMethod(colormap);

	if (method == LUT_COLOR_CUBE_SEARCH)
		func_ind += KH_MAX + 1;
	else if (method == LUT_COLOR_DIMENSIONS)
		func_ind += 2 * (KH_MAX + 1);
	func_dm = func_dm_arr[func_ind];

	for (row = 0; row < sh; row++) {
		mlib_u8 *sp = sl;

		buff = buff_arr + buff_ind;

/* convert source line */
		for (i = 0; i < sw; i++) {
			mlib_d64 ss;

			ss = LD_U8(sp, i);
			ss = vis_fmul8x16al(vis_read_lo(ss), fscale);
			ST_U16(buffd, i, ss);
		}

		pkern = kern;
		for (j = 0; j < dn; j++) {
			for (off = 0; off < m; off += kw) {
				kw = m - off;

				if (kw > KW_MAX) {
					if (kw > 2 * KW_MAX)
						kw = KW_MAX;
					else
						kw = kw / 2;
				}

				func_m_arr[kw] (buffd, buff[j] + off * NCHAN,
				    pkern + off, sw);
			}

			pkern += m;
		}

#ifdef USE_COLOR2INDEXLINE
		func_dm(buff_dst, (void *)buffd, buff[dn] + dm * NCHAN, pkern,
		    colormap, lut_table, sw, dm, 0);
/*
 * mlib_ImageColorTrue2IndexLine_U8_BIT_1
 * (buff_dst, dl, bit_offset, sw, colormap);
 */
#else /* USE_COLOR2INDEXLINE */
		func_dm(dl, (void *)buffd, buff[dn] + dm * NCHAN, pkern,
		    colormap, lut_table, sw, dm, bit_offset);
#endif /* USE_COLOR2INDEXLINE */

		buff_ind++;

		if (buff_ind >= dn1)
			buff_ind -= dn1;

		sl += sll;
		dl += dll;
	}

	__mlib_free(pbuff);

	if (kern != kern_lcl)
		__mlib_free(kern);

	return (MLIB_SUCCESS);
}
mlib_status mlib_ImageConvKernelConvert(mlib_s32       *ikernel,
                                        mlib_s32       *iscale,
                                        const mlib_d64 *fkernel,
                                        mlib_s32       m,
                                        mlib_s32       n,
                                        mlib_type      type)
{
  mlib_d64 sum_pos, sum_neg, sum, norm, max, f;
  mlib_s32 isum_pos, isum_neg, isum, test;
  mlib_s32 i, scale, scale1, chk_flag;

  if (ikernel == NULL || iscale == NULL || fkernel == NULL || m < 1 || n < 1) {
    return MLIB_FAILURE;
  }

  if ((type == MLIB_BYTE) || (type == MLIB_SHORT) || (type == MLIB_USHORT)) {

    if (type != MLIB_SHORT) {               /* MLIB_BYTE, MLIB_USHORT */
      sum_pos = 0;
      sum_neg = 0;

      for (i = 0; i < m * n; i++) {
        if (fkernel[i] > 0)
          sum_pos += fkernel[i];
        else
          sum_neg -= fkernel[i];
      }

      sum = (sum_pos > sum_neg) ? sum_pos : sum_neg;
      scale = mlib_ilogb(sum);
      scale++;

      scale = 31 - scale;
    }
    else {                                  /* MLIB_SHORT */
      sum = 0;
      max = 0;

      for (i = 0; i < m * n; i++) {
        f = mlib_fabs(fkernel[i]);
        sum += f;
        max = (max > f) ? max : f;
      }

      scale1 = mlib_ilogb(max) + 1;
      scale = mlib_ilogb(sum);
      scale = (scale > scale1) ? scale : scale1;
      scale++;

      scale = 32 - scale;
    }

    if (scale <= 16)
      return MLIB_FAILURE;
    if (scale > 31)
      scale = 31;

    *iscale = scale;

    chk_flag = mlib_ImageConvVersion(m, n, scale, type);

    if (!chk_flag) {
      norm = (1u << scale);
      for (i = 0; i < m * n; i++) {
        CLAMP_S32(ikernel[i], fkernel[i] * norm);
      }

      return MLIB_SUCCESS;
    }

    /* try to round coefficients */
#ifdef __sparc
    scale1 = 16;                            /* shift of coefficients is 16 */
#else

    if (chk_flag == 3)
      scale1 = 16;                          /* MMX */
    else
      scale1 = (type == MLIB_BYTE) ? 8 : 16;
#endif /* __sparc */
    norm = (1u << (scale - scale1));

    for (i = 0; i < m * n; i++) {
      if (fkernel[i] > 0)
        ikernel[i] = (mlib_s32) (fkernel[i] * norm + 0.5);
      else
        ikernel[i] = (mlib_s32) (fkernel[i] * norm - 0.5);
    }

    isum_pos = 0;
    isum_neg = 0;
    test = 0;

    for (i = 0; i < m * n; i++) {
      if (ikernel[i] > 0)
        isum_pos += ikernel[i];
      else
        isum_neg -= ikernel[i];
    }

    if (type == MLIB_BYTE || type == MLIB_USHORT) {
      isum = (isum_pos > isum_neg) ? isum_pos : isum_neg;

      if (isum >= (1 << (31 - scale1)))
        test = 1;
    }
    else {
      isum = isum_pos + isum_neg;

      if (isum >= (1 << (32 - scale1)))
        test = 1;
      for (i = 0; i < m * n; i++) {
        if (abs(ikernel[i]) >= (1 << (31 - scale1)))
          test = 1;
      }
    }

    if (test == 1) {                        /* rounding according scale1 cause overflow, truncate instead of round */
      for (i = 0; i < m * n; i++)
        ikernel[i] = (mlib_s32) (fkernel[i] * norm) << scale1;
    }
    else {                                  /* rounding is Ok */
      for (i = 0; i < m * n; i++)
        ikernel[i] = ikernel[i] << scale1;
    }

    return MLIB_SUCCESS;
  }
  else if ((type == MLIB_INT) || (type == MLIB_BIT)) {
    max = 0;

    for (i = 0; i < m * n; i++) {
      f = mlib_fabs(fkernel[i]);
      max = (max > f) ? max : f;
    }

    scale = mlib_ilogb(max);

    if (scale > 29)
      return MLIB_FAILURE;

    if (scale < -100)
      scale = -100;

    *iscale = 29 - scale;
    scale = 29 - scale;

    norm = 1.0;
    while (scale > 30) {
      norm *= (1 << 30);
      scale -= 30;
    }

    norm *= (1 << scale);

    for (i = 0; i < m * n; i++) {
      if (fkernel[i] > 0) {
        CLAMP_S32(ikernel[i], fkernel[i] * norm + 0.5);
      }
      else {
        CLAMP_S32(ikernel[i], fkernel[i] * norm - 0.5);
      }
    }

    return MLIB_SUCCESS;
  }
  else {
    return MLIB_FAILURE;
  }
}
Esempio n. 5
0
mlib_status
__mlib_SignalCepstral_S16_Adp(
    mlib_s16 *cepst,
    mlib_s32 *cscale,
    const mlib_s16 *signal,
    void *state)
{
	mlib_s32 i, len, itmp;
	mlib_f32 fscale;
	mlib_cepstral *str_cepst = state;
	mlib_s32 order = str_cepst->order;
	deal_t *buffer = str_cepst->buffer;
	deal_t *coeff = str_cepst->coeff;
	deal_t *coeff_s = str_cepst->coeff_s;
	mlib_s32 len_full = 1 << order;
	deal_t tmp, fmax, scale;

#if REAL_IFFT_NEEDWASTE
	len = len_full;
#else /* REAL_IFFT_NEEDWASTE */
	len = len_full / 2 + 1;
#endif /* REAL_IFFT_NEEDWASTE */

#ifdef __SUNPRO_C
#pragma nomemorydepend
#pragma pipeloop(0)
#endif /* __SUNPRO_C */
	for (i = 0; i < len_full; i++)
		buffer[i] = signal[i] / (deal_t)32768;

	mlib_fft_r2c(buffer, order);

	mlib_SignalCepstral_S16_Middle(buffer, coeff, buffer, coeff_s, 0, len);

	mlib_fft_r2r(coeff, order - 1);

	fmax = 0;
#ifdef __SUNPRO_C
#pragma nomemorydepend
#endif /* __SUNPRO_C */
	for (i = 0; i < len; i++) {
		tmp = mlib_fabsf(coeff[i]);

		if (tmp > fmax)
			fmax = tmp;
	}

	itmp = 14 - mlib_ilogb(fmax);
	SET_FLOAT_ORDER(fscale, itmp);
	scale = fscale;

#if ICOS_FFT_NEEDWASTE
#ifdef __SUNPRO_C
#pragma nomemorydepend
#pragma pipeloop(0)
#endif /* __SUNPRO_C */
	for (i = 0; i < len_full; i++)
		cepst[i] = coeff[i] * scale;
#else /* ICOS_FFT_NEEDWASTE */
	cepst[0] = coeff[0] * scale;
	cepst[len] = coeff[len] * scale;

#ifdef __SUNPRO_C
#pragma nomemorydepend
#pragma pipeloop(0)
#endif /* __SUNPRO_C */
	for (i = 1; i < len; i++) {
		cepst[i] = cepst[len_full - i] = coeff[i] * scale;
	}

#endif /* ICOS_FFT_NEEDWASTE */

	*cscale = itmp + order;
	return (MLIB_SUCCESS);
}
mlib_status
__mlib_ImageZoomTranslateTableBlend(
    mlib_image *dst,
    const mlib_image *src,
    mlib_d64 zoomx,
    mlib_d64 zoomy,
    mlib_d64 tx,
    mlib_d64 ty,
    const void *table,
    mlib_edge edge,
    mlib_blend blend,
    mlib_s32 cmask)
{
	mlib_affine_param param[1];
	mlib_affine_param *cur_param;
	mlib_zoom_workspace ws[1];
	mlib_d64 buff_lcl[BUFF_SIZE / 8];
	mlib_type type;
	mlib_u8 *srcData, *dstData;
	mlib_s32 srcWidth, dstWidth, srcHeight, dstHeight;
	mlib_s32 srcStride, dstStride, schan, dchan;
	mlib_s32 *leftEdges, *rightEdges, *xStarts, *yStarts;
	mlib_s32 *p_x_ind = NULL, *x_ind, *x_tab = NULL, xpos;
	mlib_u8 **lineAddr = NULL;
	mlib_s32 kw, kh, kw1, kh1;
	mlib_status res = MLIB_SUCCESS;
	fun_type_nw fun_nw = NULL;
	mlib_interp_table *tbl = (mlib_interp_table *) table;
	mlib_d64 mtx[6], dxs, tmp_dxs, div;
	mlib_s32 i, x_shift, y_shift;
	mlib_s32 affine = 0, yStart;
	mlib_s32 xLeft_e, xRight_e, xLeft, xRight, dx;

	mtx[0] = zoomx;
	mtx[1] = 0;
	mtx[2] = tx;
	mtx[3] = 0;
	mtx[4] = zoomy;
	mtx[5] = ty;

	ws->zoomx = zoomx;
	ws->zoomy = zoomy;

/* check for obvious errors */
	MLIB_IMAGE_CHECK(src);
	MLIB_IMAGE_CHECK(dst);
	MLIB_IMAGE_TYPE_EQUAL(src, dst);
	MLIB_IMAGE_HAVE_TYPE(src, MLIB_BYTE);

	if (zoomx <= 0 || zoomy <= 0)
		return (MLIB_OUTOFRANGE);

	if (mlib_ImageGetWidth(src) >= (1 << 15) ||
	    mlib_ImageGetHeight(src) >= (1 << 15)) {
		return (MLIB_FAILURE);
	}

	MLIB_IMAGE_GET_ALL_PARAMS(src, type, schan, srcWidth, srcHeight,
	    srcStride, srcData);
	MLIB_IMAGE_GET_ALL_PARAMS(dst, type, dchan, dstWidth, dstHeight,
	    dstStride, dstData);

	if ((schan == 4 || dchan == 4) && cmask != 1 && cmask != 8)
	    return (MLIB_OUTOFRANGE);

	if (schan < 3 || schan > 4 || dchan < 3 || dchan > 4) {
		return (MLIB_FAILURE);
	}

	if ((blend == MLIB_BLEND_GTK_SRC) && (schan == 3) && (dchan == 3))
		return __mlib_ImageZoomTranslateTable(dst, src, zoomx, zoomy,
		    tx, ty, table, edge);

	kw = tbl->width;
	kh = tbl->height;
	kw1 = tbl->leftPadding;
	kh1 = tbl->topPadding;

	x_shift = INT_BITS - mlib_ilogb(srcWidth + kw);
	y_shift = INT_BITS - mlib_ilogb(srcHeight + kh);

	ws->type = type;
	ws->srcData = srcData;
	ws->dstData = dstData;
	ws->srcWidth = srcWidth;
	ws->srcHeight = srcHeight;
	ws->srcStride = srcStride;
	ws->dstStride = dstStride;
	ws->nchan = schan;
	ws->dchan = dchan;
	ws->blend = blend;
	ws->alpha_shift = 1;
	ws->edge = edge;
	ws->x_shift = x_shift;
	ws->y_shift = y_shift;
	ws->x_move = (kw1 << x_shift);
	ws->y_move = (kh1 << y_shift);

	if (cmask == 1)
		ws->alpha_shift = -3;

/* VIS version of non NULL */
	fun_nw = mlib_ImageZoomTranslate_GetFunc(ws, table);

	if (fun_nw == NULL) {
		fun_nw = mlib_ImageZoomTranslateTableBlend_8nw;
	}

/* NULL */
	STORE_PARAM(param, affine);
	STORE_PARAM(param, lineAddr);
	param->buff_malloc = NULL;

/* process internal pixels */

	res = mlib_AffineEdges(param, dst, src, buff_lcl, BUFF_SIZE,
	    kw, kh, kw1, kh1, edge, mtx, x_shift, y_shift);

	if (res != MLIB_SUCCESS)
		return (res);

	ws->yStart = param->yStart;
	ws->yFinish = param->yFinish;
	ws->max_xsize = param->max_xsize;
	ws->dx = param->dX;
	ws->dy = param->dY;

	LOAD_PARAM(param, lineAddr);
	LOAD_PARAM(param, leftEdges);
	LOAD_PARAM(param, rightEdges);
	LOAD_PARAM(param, xStarts);
	LOAD_PARAM(param, yStarts);

	if (edge == MLIB_EDGE_SRC_EXTEND)
		ws->y_move += (1 << (y_shift - 1));

	if ((ws->max_xsize) > 0) {
/* RTC */
		yStarts[(ws->yFinish) + 1] = 0;

		res = fun_nw(param->dstData, lineAddr,
		    leftEdges, rightEdges, xStarts, yStarts, ws, tbl);

		if (res != MLIB_SUCCESS) {
			if (param->buff_malloc != NULL)
				__mlib_free(param->buff_malloc);
			return (res);
		}
	}

/* process edge pixels */

	if (edge != MLIB_EDGE_DST_NO_WRITE && edge != MLIB_EDGE_SRC_PADDED) {
		mlib_affine_param param_e[1];

		param_e->buff_malloc = NULL;

		if (edge == MLIB_EDGE_DST_FILL_ZERO ||
		    edge == MLIB_EDGE_OP_NEAREST) {
			x_shift = 16;
			y_shift = 16;
		}

		STORE_PARAM(param_e, lineAddr);

		if (edge != MLIB_EDGE_SRC_EXTEND_INDEF) {
			res = mlib_AffineEdges(param_e, dst, src, NULL, 0,
			    kw, kh, kw1, kh1, -1, mtx, x_shift, y_shift);
		}

		if (res == MLIB_SUCCESS)
			switch (edge) {
			case MLIB_EDGE_DST_FILL_ZERO:
				mlib_ImageZoomTranslateTableBlendEdgeZero
				    (param, param_e, dchan, schan,
				    ws->alpha_shift, blend);
				break;

			case MLIB_EDGE_OP_NEAREST:
				mlib_ImageZoomTranslateTableBlendEdgeNearest
				    (param, param_e, dchan, schan,
				    ws->alpha_shift, blend);
				break;

			case MLIB_EDGE_SRC_EXTEND:
			case MLIB_EDGE_SRC_EXTEND_INDEF:

				ws->x_shift = x_shift;
				ws->x_move += (1 << (x_shift - 1));

				if (edge == MLIB_EDGE_SRC_EXTEND) {
					ws->yStart = param_e->yStart;
					ws->yFinish = param_e->yFinish;
					yStart = ws->yStart;
					ws->dx = param_e->dX;
					xLeft_e = param_e->leftEdges[yStart];
					xRight_e = param_e->rightEdges[yStart];
					cur_param = param_e;

				} else {
					cur_param = param;
					ws->yStart = param->yStart;
					yStart = ws->yStart;
					xLeft_e = 0;
					xRight_e = dstWidth - 1;
				}

				xLeft = param->leftEdges[param->yStart];
				xRight = param->rightEdges[param->yStart];

				if ((xLeft > xRight) ||
				    (param->yStart > param->yFinish)) {
					xLeft = xRight_e + 1;
					xRight = xRight_e;
				}

				if (((xRight_e - xLeft_e + 1) > 0) &&
				    (ws->yStart <= ws->yFinish)) {
					CREATE_X_IND();

					LOAD_PARAM(cur_param, lineAddr);
					LOAD_PARAM(cur_param, leftEdges);
					LOAD_PARAM(cur_param, xStarts);
					LOAD_PARAM(cur_param, yStarts);

/* RTC */
					yStarts[(ws->yFinish) + 1] = 0;

					if (edge == MLIB_EDGE_SRC_EXTEND) {
						CREATE_X_EXT()
					}

					ws->max_xsize = xLeft - xLeft_e;

					if ((ws->max_xsize) > 0) {
						if (edge !=
						    MLIB_EDGE_SRC_EXTEND) {
							CREATE_X(xLeft_e,
							    xLeft - 1);
						}

						leftEdges[0] = ws->max_xsize;
						leftEdges[1] = xLeft_e;

						res = FUNCNAME_EXT
						    (cur_param->dstData,
						    lineAddr, x_ind, leftEdges,
						    x_tab, xStarts, yStarts, ws,
						    tbl);
					}

					ws->max_xsize = xRight_e - xRight;

					if ((ws->max_xsize) > 0) {
						mlib_s32 shift = 0;

						if (edge !=
						    MLIB_EDGE_SRC_EXTEND) {
							CREATE_X(xRight + 1,
							    xRight_e);
						} else {
							shift =
							    xRight + 1 -
							    xLeft_e;
						}

						leftEdges[0] = ws->max_xsize;
						leftEdges[1] = xRight + 1;

						res = FUNCNAME_EXT
						    (cur_param->dstData,
						    lineAddr, x_ind, leftEdges,
						    x_tab + shift, xStarts,
						    yStarts, ws, tbl);
					}

					__mlib_free(p_x_ind);

					if (x_tab != NULL)
						__mlib_free(x_tab);
				}
				break;
			default:
				res = MLIB_FAILURE;
				break;
			}
Esempio n. 7
0
mlib_status
mlib_m_ImageInitInterpTableAffine_S16(
    mlib_interp_table * table,
    mlib_s32 nchan)
{
	mlib_s32 width, height, width_bits, height_bits, vis_width_bits,
	    vis_height_bits;
	mlib_s32 subsampleBitsH, subsampleBitsV;
	mlib_s32 i, j, c, scale, num_copy, num_copy_old;
	mlib_s32 isum;
	mlib_s32 max_scale, min_scale, scaleh, scalev;
	mlib_s32 norm_scale_v, norm_scale_h;
	mlib_d64 dscale, *dataH, *dataV;
	mlib_d64 **ptr_tablex, *tablex, *tablex_old, *tabley;
	mlib_d64 max, d;
	mlib_d64 sumh, sumv, normh, normv;

	if (!table)
		return (MLIB_FAILURE);
	if (table->shift_vis_affine < 0)
		return (MLIB_FAILURE);

	if (nchan == 1) {
		num_copy = 1;
		ptr_tablex = &(table->dataH_s16_1);
	} else if (nchan == 2) {
		num_copy = 2;
		ptr_tablex = &(table->dataH_s16_3);
	} else if (nchan == 3 || nchan == 4) {
		num_copy = 4;
		ptr_tablex = &(table->dataH_s16_4);
	} else
		return (MLIB_FAILURE);

	if (*ptr_tablex != NULL && table->dataV_s16_1 != NULL)
		return (MLIB_SUCCESS);

	dataH = mlib_ImageGetInterpDoubleDataH(table);
	dataV = mlib_ImageGetInterpDoubleDataV(table);
	if (!dataH || !dataV)
		return (MLIB_FAILURE);

	width = mlib_ImageGetInterpWidth(table);
	height = mlib_ImageGetInterpHeight(table);
	width_bits = mlib_ImageGetInterpWidthBits(table);
	height_bits = mlib_ImageGetInterpHeightBits(table);
	vis_width_bits = table->vis_width_bits;
	vis_height_bits = table->vis_height_bits;
	subsampleBitsH = mlib_ImageGetInterpSubsampleBitsH(table);
	subsampleBitsV = mlib_ImageGetInterpSubsampleBitsV(table);

	if (table->dataV_s16_1 != NULL) {
		if (table->dataH_s16_1 != NULL) {
			tablex_old = table->dataH_s16_1;
			num_copy_old = 1;
		} else if (table->dataH_s16_3 != NULL) {
			tablex_old = table->dataH_s16_3;
			num_copy_old = 3;
		} else {
			tablex_old = table->dataH_s16_4;
			num_copy_old = 4;
		}

		tablex =
		    mlib_malloc(num_copy * (1 << subsampleBitsH) *
		    (1 << vis_width_bits) * sizeof (mlib_s16));
		if (tablex == NULL)
			return (MLIB_FAILURE);

		for (j = 0; j < ((width + 1) & ~1); j++) {
			mlib_s16 *tbl = (mlib_s16 *)tablex + j * num_copy;
			mlib_s16 *tbl_old =
			    (mlib_s16 *)tablex_old + j * num_copy_old;
			for (i = 0; i < (1 << subsampleBitsH); i++) {
				mlib_s16 v =
				    tbl_old[num_copy_old *
				    (i << vis_width_bits)];
				for (c = 0; c < num_copy; c++) {
					tbl[num_copy * (i << vis_width_bits) +
					    c] = v;
				}
			}
		}
		*ptr_tablex = tablex;
		return (MLIB_SUCCESS);
	}

	sumv = 0;
	max = 0;

	for (i = 0; i < (1 << subsampleBitsV); i++) {
		mlib_d64 s = 0;
		mlib_s32 ind = (i << height_bits);

		for (j = 0; j < height; j++) {
			d = mlib_fabs(dataV[j + ind]);
			s += d;
			max = (max > d) ? max : d;
		}
		sumv = (sumv > s) ? sumv : s;
	}

/* all fhkernels = 0 */
	if (sumv == 0) {
		dscale = 0;

/* X table */

		tablex =
		    mlib_malloc(num_copy * (1 << subsampleBitsH) *
		    (1 << vis_width_bits) * sizeof (mlib_s16));
		if (tablex == NULL)
			return (MLIB_FAILURE);

		INIT_TABLE_16(tablex, (1 << subsampleBitsH), width, width_bits,
		    vis_width_bits, dataH);

		if ((dataH == dataV) && num_copy == 4)
			tabley = tablex;
		else {

			num_copy = 4;

			tabley =
			    mlib_malloc(num_copy * (1 << subsampleBitsV) *
			    (1 << vis_height_bits) * sizeof (mlib_s16));
			if (tabley == NULL) {
				mlib_free(tablex);
				return (MLIB_FAILURE);
			}

			INIT_TABLE_16(tabley, (1 << subsampleBitsV), height,
			    height_bits, vis_height_bits, dataV);

			*ptr_tablex = tablex;
			table->dataV_s16_1 = tabley;

/* Store shift */
			table->shift_vis_affine = 43;

			return (MLIB_SUCCESS);
		}
	}

	normv = 32767.0 / (32768.0 * sumv);
	scalev = mlib_ilogb(sumv * normv);
	isum = mlib_ilogb(max * normv);

/* all elements must be in the range -32768, 32767 */
	if (scalev == isum)
		norm_scale_v = 14;
/* but sumv may be in the range -65576, 65575 */
	else
		norm_scale_v = 15;

	min_scale = 25;
	max_scale = 40;

	normh = 32768.0 * sumv / 32767;

	if (dataH != dataV) {
		sumh = 0;
		max = 0;

		for (i = 0; i < (1 << subsampleBitsH); i++) {
			mlib_d64 s = 0;
			mlib_s32 ind = (i << width_bits);

			for (j = 0; j < width; j++) {
				d = mlib_fabs(dataH[j + ind]);
				s += d;
				max = (max > d) ? max : d;
			}
			sumh = (sumh > s) ? sumh : s;
		}
	} else
		sumh = sumv;

	isum = mlib_ilogb(max * normh);
	scaleh = mlib_ilogb(sumh * normh);

/* all elements must be in the range -32768, 32767 */
	if (scaleh == isum)
		norm_scale_h = 14;
/* but sumh may be in the range -65576, 65575 */
	else
		norm_scale_h = 15;

	scale = norm_scale_v + norm_scale_h - (scaleh + scalev);

	if (scale < min_scale) {
		table->shift_vis_affine = -1;
/* koeff. are so large */
		return (MLIB_FAILURE);
	}

	if (scale > max_scale) {
		scaleh += (scale - max_scale + 1) >> 1;
		scalev += (scale - max_scale) >> 1;
		scale = max_scale;
	}