void mlib_ImageAffineEdgeZero(mlib_affine_param *param,
                              mlib_affine_param *param_e,
                              const void        *colormap)
{
  GET_EDGE_PARAMS_ZERO();
  mlib_s32 zero = 0;

  if (colormap != NULL) {
    zero = mlib_ImageGetLutOffset(colormap);
  }

  switch (type) {
    case MLIB_BYTE:
      MLIB_PROCESS_EDGES_ZERO(mlib_u8);
      break;

    case MLIB_SHORT:
    case MLIB_USHORT:
      MLIB_PROCESS_EDGES_ZERO(mlib_s16);
      break;

    case MLIB_INT:
    case MLIB_FLOAT:
      MLIB_PROCESS_EDGES_ZERO(mlib_s32);
      break;

    case MLIB_DOUBLE:{
        mlib_d64 zero = 0;
        MLIB_PROCESS_EDGES_ZERO(mlib_d64);
        break;
      }
  }
}
mlib_status
__mlib_ImageConv5x5Index(
    mlib_image *dst,
    const mlib_image *src,
    const mlib_s32 *kernel,
    mlib_s32 scale,
    mlib_edge edge,
    const void *colormap)
{
    mlib_status stat;
    mlib_type src_dtype, lut_type;
    mlib_s32 zero[4];
    mlib_s32 offset;

    if (dst == NULL || src == NULL || colormap == NULL || kernel == NULL)
        return (MLIB_FAILURE);

    MLIB_IMAGE_FULL_EQUAL(dst, src);
    MLIB_IMAGE_HAVE_CHAN(src, 1);

    src_dtype = mlib_ImageGetType(src);
    lut_type = mlib_ImageGetLutType(colormap);
    offset = (mlib_s32)mlib_ImageGetLutOffset(colormap);
    zero[0] = zero[1] = zero[2] = zero[3] = offset;

    if (mlib_ImageGetWidth(src) < 5 || mlib_ImageGetHeight(src) < 5)
        return (MLIB_FAILURE);

    if (((lut_type == MLIB_BYTE) && (scale < 16 || scale > 31)) ||
            ((lut_type == MLIB_SHORT) && (scale < 17 || scale > 32)))
        return (MLIB_FAILURE);

    switch (src_dtype) {
    case MLIB_BYTE:
        switch (lut_type) {
        case MLIB_BYTE:
            switch (edge) {
            case MLIB_EDGE_DST_FILL_ZERO:
                stat =
                    mlib_v_conv5x5Index_8_8nw(src, dst, kernel,
                                              scale, colormap);

                if (stat != MLIB_SUCCESS)
                    break;
                stat =
                    mlib_ImageConvClearEdge(dst, 2, 2, 2, 2,
                                            zero, 1);
                break;
            case MLIB_EDGE_DST_COPY_SRC:
                stat =
                    mlib_v_conv5x5Index_8_8nw(src, dst, kernel,
                                              scale, colormap);

                if (stat != MLIB_SUCCESS)
                    break;
                stat =
                    mlib_ImageConvCopyEdge(dst, src, 2, 2, 2, 2,
                                           1);
                break;
            case MLIB_EDGE_SRC_EXTEND:
                stat =
                    mlib_v_conv5x5Index_8_8ext(src, dst, kernel,
                                               scale, colormap);
                break;
            case MLIB_EDGE_DST_NO_WRITE:
            default:
                stat =
                    mlib_v_conv5x5Index_8_8nw(src, dst, kernel,
                                              scale, colormap);
                break;
            }

            break;
        case MLIB_SHORT:
            switch (edge) {
            case MLIB_EDGE_DST_FILL_ZERO:
                stat =
                    mlib_conv5x5Index_16_8nw(src, dst, kernel,
                                             scale, colormap);

                if (stat != MLIB_SUCCESS)
                    break;
                stat =
                    mlib_ImageConvClearEdge(dst, 2, 2, 2, 2,
                                            zero, 1);
                break;
            case MLIB_EDGE_DST_COPY_SRC:
                stat =
                    mlib_conv5x5Index_16_8nw(src, dst, kernel,
                                             scale, colormap);

                if (stat != MLIB_SUCCESS)
                    break;
                stat =
                    mlib_ImageConvCopyEdge(dst, src, 2, 2, 2, 2,
                                           1);
                break;
            case MLIB_EDGE_SRC_EXTEND:
                stat =
                    mlib_conv5x5Index_16_8ext(src, dst, kernel,
                                              scale, colormap);
                break;
            case MLIB_EDGE_DST_NO_WRITE:
            default:
                stat =
                    mlib_conv5x5Index_16_8nw(src, dst, kernel,
                                             scale, colormap);
                break;
            }

            break;
        }

        break;
    case MLIB_SHORT:	/* convert wid from pixels to bytes */
        switch (lut_type) {
        case MLIB_SHORT:
            switch (edge) {
            case MLIB_EDGE_DST_FILL_ZERO:
                stat =
                    mlib_conv5x5Index_16_16nw(src, dst, kernel,
                                              scale, colormap);

                if (stat != MLIB_SUCCESS)
                    break;
                stat =
                    mlib_ImageConvClearEdge(dst, 2, 2, 2, 2,
                                            zero, 1);
                break;
            case MLIB_EDGE_DST_COPY_SRC:
                stat =
                    mlib_conv5x5Index_16_16nw(src, dst, kernel,
                                              scale, colormap);

                if (stat != MLIB_SUCCESS)
                    break;
                stat =
                    mlib_ImageConvCopyEdge(dst, src, 2, 2, 2, 2,
                                           1);
                break;
            case MLIB_EDGE_SRC_EXTEND:
                stat =
                    mlib_conv5x5Index_16_16ext(src, dst, kernel,
                                               scale, colormap);
                break;
            case MLIB_EDGE_DST_NO_WRITE:
            default:
                stat =
                    mlib_conv5x5Index_16_16nw(src, dst, kernel,
                                              scale, colormap);
                break;
            }

            break;
        case MLIB_BYTE:
            switch (edge) {
            case MLIB_EDGE_DST_FILL_ZERO:
                stat =
                    mlib_v_conv5x5Index_8_16nw(src, dst, kernel,
                                               scale, colormap);

                if (stat != MLIB_SUCCESS)
                    break;
                stat =
                    mlib_ImageConvClearEdge(dst, 2, 2, 2, 2,
                                            zero, 1);
                break;
            case MLIB_EDGE_DST_COPY_SRC:
                stat =
                    mlib_v_conv5x5Index_8_16nw(src, dst, kernel,
                                               scale, colormap);

                if (stat != MLIB_SUCCESS)
                    break;
                stat =
                    mlib_ImageConvCopyEdge(dst, src, 2, 2, 2, 2,
                                           1);
                break;
            case MLIB_EDGE_SRC_EXTEND:
                stat =
                    mlib_v_conv5x5Index_8_16ext(src, dst,
                                                kernel, scale, colormap);
                break;
            case MLIB_EDGE_DST_NO_WRITE:
            default:
                stat =
                    mlib_v_conv5x5Index_8_16nw(src, dst, kernel,
                                               scale, colormap);
                break;
            }

            break;
        }

        break;
    default:
        stat = MLIB_FAILURE;
        break;
    }

    return (stat);
}
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);
}
示例#4
0
mlib_status
__mlib_ImageZoomTranslateIndex(
    mlib_image *dst,
    const mlib_image *src,
    mlib_d64 zoomx,
    mlib_d64 zoomy,
    mlib_d64 tx,
    mlib_d64 ty,
    mlib_filter filter,
    mlib_edge edge,
    const void *colormap)
{
	mlib_s32 mask, len;
	mlib_clipping nearest, current;
	mlib_work_image border;
	mlib_status stat;

	if (filter == MLIB_NEAREST)
		return __mlib_ImageZoomTranslate(dst, src, zoomx, zoomy, tx, ty,
		    filter, edge);

	MLIB_IMAGE_CHECK(src);
	MLIB_IMAGE_CHECK(dst);
	MLIB_IMAGE_TYPE_EQUAL(src, dst);
	MLIB_IMAGE_HAVE_CHAN(src, 1);
	MLIB_IMAGE_HAVE_CHAN(dst, 1);

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

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

	border.nearest = &nearest;
	border.current = &current;

	mlib_ImageZoomClipping(dst, src, zoomx, zoomy, tx, ty, filter, edge,
	    &border);

	border.colormap = (void *)colormap;
	border.color = mlib_ImageGetLutOffset(colormap);

	len = mlib_ImageGetWidth(dst);

	if (len < mlib_ImageGetHeight(dst))
		len = mlib_ImageGetHeight(dst);

	border.buffer_dp =
	    __mlib_malloc(len * (mlib_ImageGetLutType(colormap) ==
	    MLIB_SHORT ? sizeof (mlib_d64) : sizeof (mlib_f32)));

	if (border.buffer_dp == NULL)
		return (MLIB_FAILURE);

	mask = (mlib_ImageGetType(src) << 8) | mlib_ImageGetLutType(colormap);

	if (current.width == 0)
		goto jmp_edge;

	switch (filter) {

	case MLIB_BILINEAR:

		switch (mlib_ImageGetLutChannels(colormap)) {

		case 3:

			switch (mask) {

			/* index : MLIB_BYTE, pal : MLIB_BYTE */
			case (MLIB_BYTE << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_U8_U8_3_Bilinear
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_SHORT */
			case (MLIB_SHORT << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_S16_S16_3_Bilinear
				    (&border);
				break;

			/* index : MLIB_BYTE, pal : MLIB_SHORT */
			case (MLIB_BYTE << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_U8_S16_3_Bilinear
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_BYTE */
			case (MLIB_SHORT << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_S16_U8_3_Bilinear
				    (&border);
				break;

			default:
				__mlib_free(border.buffer_dp);
				return (MLIB_FAILURE);
			}

/* case 3 */
			break;

		case 4:

			/* index : MLIB_BYTE, pal : MLIB_BYTE */
			switch (mask) {
			case (MLIB_BYTE << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_U8_U8_4_Bilinear
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_SHORT */
			case (MLIB_SHORT << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_S16_S16_4_Bilinear
				    (&border);
				break;

			/* index : MLIB_BYTE, pal : MLIB_SHORT */
			case (MLIB_BYTE << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_U8_S16_4_Bilinear
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_BYTE */
			case (MLIB_SHORT << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_S16_U8_4_Bilinear
				    (&border);
				break;

			default:
				__mlib_free(border.buffer_dp);
				return (MLIB_FAILURE);
			}

/* case 4 */
			break;

		default:
			__mlib_free(border.buffer_dp);
			return (MLIB_FAILURE);
		}

/* case MLIB_BILINEAR */
		break;

	case MLIB_BICUBIC:

		switch (mlib_ImageGetLutChannels(colormap)) {

		case 3:

			switch (mask) {
			/* index : MLIB_BYTE, pal : MLIB_BYTE */
			case (MLIB_BYTE << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_U8_U8_3_Bicubic
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_SHORT */
			case (MLIB_SHORT << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_S16_S16_3_Bicubic
				    (&border);
				break;

			/* index : MLIB_BYTE, pal : MLIB_SHORT */
			case (MLIB_BYTE << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_U8_S16_3_Bicubic
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_BYTE */
			case (MLIB_SHORT << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_S16_U8_3_Bicubic
				    (&border);
				break;

			default:
				__mlib_free(border.buffer_dp);
				return (MLIB_FAILURE);
			}

/* case 3 */
			break;

		case 4:

			switch (mask) {
			/* index : MLIB_BYTE, pal : MLIB_BYTE */
			case (MLIB_BYTE << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_U8_U8_4_Bicubic
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_SHORT */
			case (MLIB_SHORT << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_S16_S16_4_Bicubic
				    (&border);
				break;

			/* index : MLIB_BYTE, pal : MLIB_SHORT */
			case (MLIB_BYTE << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_U8_S16_4_Bicubic
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_BYTE */
			case (MLIB_SHORT << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_S16_U8_4_Bicubic
				    (&border);
				break;

			default:
				__mlib_free(border.buffer_dp);
				return (MLIB_FAILURE);
			}

/* case 4 */
			break;

		default:
			__mlib_free(border.buffer_dp);
			return (MLIB_FAILURE);
		}

/* case MLIB_BICUBIC */
		break;

	case MLIB_BICUBIC2:

		switch (mlib_ImageGetLutChannels(colormap)) {

		case 3:

			switch (mask) {
			/* index : MLIB_BYTE, pal : MLIB_BYTE */
			case (MLIB_BYTE << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_U8_U8_3_Bicubic2
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_SHORT */
			case (MLIB_SHORT << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_S16_S16_3_Bicubic2
				    (&border);
				break;

			/* index : MLIB_BYTE, pal : MLIB_SHORT */
			case (MLIB_BYTE << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_U8_S16_3_Bicubic2
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_BYTE */
			case (MLIB_SHORT << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_S16_U8_3_Bicubic2
				    (&border);
				break;

			default:
				__mlib_free(border.buffer_dp);
				return (MLIB_FAILURE);
			}

/* case 3 */
			break;

		case 4:

			switch (mask) {
			/* index : MLIB_BYTE, pal : MLIB_BYTE */
			case (MLIB_BYTE << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_U8_U8_4_Bicubic2
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_SHORT */
			case (MLIB_SHORT << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_S16_S16_4_Bicubic2
				    (&border);
				break;

			/* index : MLIB_BYTE, pal : MLIB_SHORT */
			case (MLIB_BYTE << 8) | MLIB_SHORT:
				stat =
				    mlib_c_ImageZoomIndex_U8_S16_4_Bicubic2
				    (&border);
				break;

			/* index : MLIB_SHORT, pal : MLIB_BYTE */
			case (MLIB_SHORT << 8) | MLIB_BYTE:
				stat =
				    mlib_c_ImageZoomIndex_S16_U8_4_Bicubic2
				    (&border);
				break;

			default:
				__mlib_free(border.buffer_dp);
				return (MLIB_FAILURE);
			}

/* case 4 */
			break;

		default:
			__mlib_free(border.buffer_dp);
			return (MLIB_FAILURE);
		}

/* case MLIB_BICUBIC2 */
		break;

	default:
		__mlib_free(border.buffer_dp);
		return (MLIB_FAILURE);
	}

	if (stat != MLIB_SUCCESS) {
		__mlib_free(border.buffer_dp);
		return (MLIB_FAILURE);
	}

jmp_edge:
	switch (edge) {

	case MLIB_EDGE_DST_FILL_ZERO:

		switch (mlib_ImageGetType(src)) {
		case MLIB_BYTE:
			mlib_ImageZoomZeroEdge_U8(&border);
			break;

		case MLIB_SHORT:
			mlib_ImageZoomZeroEdge_S16(&border);
			break;
		default:
			__mlib_free(border.buffer_dp);
			return (MLIB_FAILURE);
		}

		break;

	case MLIB_EDGE_OP_NEAREST:

		switch (mlib_ImageGetType(src)) {
		case MLIB_BYTE:
			mlib_ImageZoomUpNearest_U8(&border);
			break;

		case MLIB_SHORT:
			mlib_ImageZoomUpNearest_S16(&border);
			break;
		default:
			__mlib_free(border.buffer_dp);
			return (MLIB_FAILURE);
		}

		break;

	case MLIB_EDGE_SRC_EXTEND:

		switch (mlib_ImageGetType(src)) {
		case MLIB_BYTE:

			switch (filter) {
			case MLIB_BILINEAR:
				mlib_ImageZoomIndexExtend_U8_Bilinear(&border);
				break;

			case MLIB_BICUBIC:
				mlib_ImageZoomIndexExtend_U8_Bicubic(&border);
				break;

			case MLIB_BICUBIC2:
				mlib_ImageZoomIndexExtend_U8_Bicubic2(&border);
				break;
			default:
				__mlib_free(border.buffer_dp);
				return (MLIB_FAILURE);
			}

			break;

		case MLIB_SHORT:
			switch (filter) {
			case MLIB_BILINEAR:
				mlib_ImageZoomIndexExtend_S16_Bilinear(&border);
				break;

			case MLIB_BICUBIC:
				mlib_ImageZoomIndexExtend_S16_Bicubic(&border);
				break;

			case MLIB_BICUBIC2:
				mlib_ImageZoomIndexExtend_S16_Bicubic2(&border);
				break;
			default:
				__mlib_free(border.buffer_dp);
				return (MLIB_FAILURE);
			}

			break;
		default:
			__mlib_free(border.buffer_dp);
			return (MLIB_FAILURE);
		}

		break;

	case MLIB_EDGE_DST_NO_WRITE:
	case MLIB_EDGE_DST_COPY_SRC:
	case MLIB_EDGE_OP_DEGRADED:
	case MLIB_EDGE_SRC_EXTEND_ZERO:
	case MLIB_EDGE_SRC_EXTEND_MIRROR:
	case MLIB_EDGE_SRC_PADDED:
	default:
		__mlib_free(border.buffer_dp);
		return (MLIB_SUCCESS);
	}

	__mlib_free(border.buffer_dp);
	return (MLIB_SUCCESS);
}
void
mlib_ImageZoomIndexExtend_U8_Bicubic2(
	mlib_work_image * param)
{
	VARIABLE_EDGE(mlib_u8);
	VARIABLE_SRC_EXTEND(mlib_u8);

	VARIABLE_SRC_EXTEND_BC;
	void *colormap = GetElemStruct(colormap);
	mlib_type colortype = mlib_ImageGetLutType(colormap);
	mlib_pack_func pack_func;
	mlib_u8 *tdpbuf = GetElemStruct(buffer_dp);

	channels = mlib_ImageGetLutChannels(colormap);

	if (colortype == MLIB_BYTE) {
		mlib_u8 *csp, *dpbuf = GetElemStruct(buffer_dp);
		mlib_f32 *ctable =
			(mlib_f32 *)mlib_ImageGetLutNormalTable(colormap) -
			mlib_ImageGetLutOffset(colormap);

		if (channels == 3)
			pack_func =
				(mlib_pack_func) &
				mlib_ImageColorTrue2IndexLine_U8_U8_3;
		else
			pack_func =
				(mlib_pack_func) &
				mlib_ImageColorTrue2IndexLine_U8_U8_4;

/* *********************************************************** */

#if defined(MLIB_XY_SHIFT)
#undef MLIB_XY_SHIFT
#define	MLIB_XY_SHIFT	4
#endif /* defined(MLIB_XY_SHIFT) */

/* *********************************************************** */

#if defined(MLIB_XY_MASK)
#undef MLIB_XY_MASK
#define	MLIB_XY_MASK	(((1 << 8) - 1) << 4)
#endif /* defined(MLIB_XY_MASK) */

		MLIB_SRC_EXTEND_INDEX_BC(mlib_u8,
			dp0,
			x,
			y,
			w,
			h,
			r,
			c,
			x0,
			y0,
			w1,
			h1,
			mlib_filters_u8f_bc2,
			RES_U8_INDEX,
			HOR);
		MLIB_SRC_EXTEND_INDEX_BC(mlib_u8,
			dp3,
			x,
			y,
			w,
			h,
			r,
			c,
			x0,
			y2,
			w1,
			h3,
			mlib_filters_u8f_bc2,
			RES_U8_INDEX,
			HOR);
		MLIB_SRC_EXTEND_INDEX_BC(mlib_u8,
			dp1,
			y,
			x,
			h,
			w,
			c,
			r,
			y1,
			x0,
			h2,
			w2,
			mlib_filters_u8f_bc2,
			RES_U8_INDEX,
			VER);
		MLIB_SRC_EXTEND_INDEX_BC(mlib_u8,
			dp2,
			y,
			x,
			h,
			w,
			c,
			r,
			y1,
			x1,
			h2,
			w3,
			mlib_filters_u8f_bc2,
			RES_U8_INDEX,
			VER);
	} else {
		mlib_s16 *csp, *dpbuf = GetElemStruct(buffer_dp);
		mlib_d64 *ctable =
			(mlib_d64 *)mlib_ImageGetLutNormalTable(colormap) -
			mlib_ImageGetLutOffset(colormap);

		if (channels == 3)
			pack_func =
				(mlib_pack_func) &
				mlib_ImageColorTrue2IndexLine_S16_U8_3;
		else
			pack_func =
				(mlib_pack_func) &
				mlib_ImageColorTrue2IndexLine_S16_U8_4;

/* *********************************************************** */

#if defined(MLIB_XY_SHIFT)
#undef MLIB_XY_SHIFT
#define	MLIB_XY_SHIFT	3
#endif /* defined(MLIB_XY_SHIFT) */

/* *********************************************************** */

#if defined(MLIB_XY_MASK)
#undef MLIB_XY_MASK
#define	MLIB_XY_MASK	(((1 << 9) - 1) << 4)
#endif /* defined(MLIB_XY_MASK) */

		MLIB_SRC_EXTEND_INDEX_BC(mlib_s16,
			dp0,
			x,
			y,
			w,
			h,
			r,
			c,
			x0,
			y0,
			w1,
			h1,
			mlib_filters_s16f_bc2,
			RES_S16_INDEX,
			HOR);
		MLIB_SRC_EXTEND_INDEX_BC(mlib_s16,
			dp3,
			x,
			y,
			w,
			h,
			r,
			c,
			x0,
			y2,
			w1,
			h3,
			mlib_filters_s16f_bc2,
			RES_S16_INDEX,
			HOR);
		MLIB_SRC_EXTEND_INDEX_BC(mlib_s16,
			dp1,
			y,
			x,
			h,
			w,
			c,
			r,
			y1,
			x0,
			h2,
			w2,
			mlib_filters_s16f_bc2,
			RES_S16_INDEX,
			VER);
		MLIB_SRC_EXTEND_INDEX_BC(mlib_s16,
			dp2,
			y,
			x,
			h,
			w,
			c,
			r,
			y1,
			x1,
			h2,
			w3,
			mlib_filters_s16f_bc2,
			RES_S16_INDEX,
			VER);
	}
}
void
mlib_ImageZoomIndexExtend_S16_Bilinear(
	mlib_work_image * param)
{
	VARIABLE_EDGE(mlib_s16);
	VARIABLE_SRC_EXTEND(mlib_s16);
	void *colormap = GetElemStruct(colormap);
	mlib_type colortype = mlib_ImageGetLutType(colormap);
	mlib_pack_func pack_func;
	mlib_s16 *tdpbuf = GetElemStruct(buffer_dp);

	channels = mlib_ImageGetLutChannels(colormap);

	if (colortype == MLIB_BYTE) {
		mlib_u8 *csp, *dpbuf = GetElemStruct(buffer_dp);
		mlib_f32 *ctable =
			(mlib_f32 *)mlib_ImageGetLutNormalTable(colormap) -
			mlib_ImageGetLutOffset(colormap);

		if (channels == 3)
			pack_func =
				(mlib_pack_func) &
				mlib_ImageColorTrue2IndexLine_U8_S16_3;
		else
			pack_func =
				(mlib_pack_func) &
				mlib_ImageColorTrue2IndexLine_U8_S16_4;

		MLIB_SRC_EXTEND_INDEX_BL(mlib_u8,
			dp0,
			x,
			y,
			w,
			h,
			x0,
			y0,
			w1,
			h1,
			HOR);
		MLIB_SRC_EXTEND_INDEX_BL(mlib_u8,
			dp3,
			x,
			y,
			w,
			h,
			x0,
			y2,
			w1,
			h3,
			HOR);
		MLIB_SRC_EXTEND_INDEX_BL(mlib_u8,
			dp1,
			y,
			x,
			h,
			w,
			y1,
			x0,
			h2,
			w2,
			VER);
		MLIB_SRC_EXTEND_INDEX_BL(mlib_u8,
			dp2,
			y,
			x,
			h,
			w,
			y1,
			x1,
			h2,
			w3,
			VER);
	} else {
		mlib_s16 *csp, *dpbuf = GetElemStruct(buffer_dp);
		mlib_d64 *ctable =
			(mlib_d64 *)mlib_ImageGetLutNormalTable(colormap) -
			mlib_ImageGetLutOffset(colormap);

		if (channels == 3)
			pack_func =
				(mlib_pack_func) &
				mlib_ImageColorTrue2IndexLine_S16_S16_3;
		else
			pack_func =
				(mlib_pack_func) &
				mlib_ImageColorTrue2IndexLine_S16_S16_4;

		MLIB_SRC_EXTEND_INDEX_BL(mlib_s16,
			dp0,
			x,
			y,
			w,
			h,
			x0,
			y0,
			w1,
			h1,
			HOR);
		MLIB_SRC_EXTEND_INDEX_BL(mlib_s16,
			dp3,
			x,
			y,
			w,
			h,
			x0,
			y2,
			w1,
			h3,
			HOR);
		MLIB_SRC_EXTEND_INDEX_BL(mlib_s16,
			dp1,
			y,
			x,
			h,
			w,
			y1,
			x0,
			h2,
			w2,
			VER);
		MLIB_SRC_EXTEND_INDEX_BL(mlib_s16,
			dp2,
			y,
			x,
			h,
			w,
			y1,
			x1,
			h2,
			w3,
			VER);
	}
}
mlib_status mlib_ImageAffineEdgeExtend_BL(mlib_affine_param *param,
                                          mlib_affine_param *param_e,
                                          const void        *colormap)
{
  GET_EDGE_PARAMS();
  mlib_d64 scale = 1.0 / (mlib_d64) MLIB_PREC;
  mlib_s32 xDelta, yDelta, xFlag, yFlag;
  mlib_d64 t, u, pix0;
  mlib_d64 a00, a01, a10, a11;

  if (colormap != NULL) {
    mlib_s32 max_xsize = param_e->max_xsize;
    mlib_type ltype = mlib_ImageGetLutType(colormap);
    mlib_d64 *plut = (mlib_d64 *) mlib_ImageGetLutDoubleData(colormap);
    void *buff;

    channels = mlib_ImageGetLutChannels(colormap);
    plut -= channels * mlib_ImageGetLutOffset(colormap);

    if (max_xsize == 0) {
      return MLIB_SUCCESS;
    }

    if (ltype == MLIB_BYTE) {
      buff = mlib_malloc(channels * max_xsize);
    }
    else {
      buff = mlib_malloc(channels * max_xsize * sizeof(mlib_s16));
    }

    if (buff == NULL)
      return MLIB_FAILURE;

    switch (ltype) {
      case MLIB_BYTE:
        switch (type) {
          case MLIB_BYTE:
            MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_u8i, mlib_u8);
            break;

          case MLIB_SHORT:
            srcStride >>= 1;
            MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_u8i, mlib_s16);
            break;
        }

        break;

      case MLIB_SHORT:
        switch (type) {
          case MLIB_BYTE:
            MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_s16i, mlib_u8);
            break;

          case MLIB_SHORT:
            srcStride >>= 1;
            MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_s16i, mlib_s16);
            break;
        }

        break;
    }

    mlib_free(buff);

    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_s64 *pbuff, *buffd, *buff_lcl[2 * MAX_N], **buff_arr =
	    buff_lcl, **buff;
	mlib_s32 kern_lcl[MAX_N * MAX_M], *kern = kern_lcl, *pkern;
	mlib_s64 dscale;

	func_dm_type func_dm;
	mlib_s32 bit_offset;

	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);
	}

	dn = n - 1 - dn;
	dm = m - 1 - dm;

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

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

	}

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

	kernel += m * n - 1;
	for (i = 0; i < (m * dn + dm); i++) {
		kern[i] = kernel[-i];
	}

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

	bsize = (sw + m) * NCHAN;
	dn1 = (dn) ? dn : 1;
	pbuff = __mlib_malloc((dn1 + 1) * bsize * sizeof (mlib_s64));

	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 = pbuff + dn1 * bsize;

/* clear buffer */
	for (i = 0; i < dn * bsize; i++) {
		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++) {
		buff = buff_arr + buff_ind;

/* convert source line to mlib_d64 */
		for (i = 0; i < sw * NCHAN; i++) {
			buffd[i] = sl[i] * dscale;
		}

		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;
		}

		func_dm(dl, buffd, buff[dn] + dm * NCHAN,
			pkern, dscale, colormap,
		    lut_table, sw, dm, bit_offset);

		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);
}
示例#9
0
mlib_status
__mlib_ImageConvMxNIndex(
    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,
    mlib_edge edge,
    const void *colormap)
{
    mlib_image dst_i[1], src_i[1], dst_e[1], src_e[1];
    mlib_type  img_type, lut_type;
    mlib_s32   offset, func_index;
    mlib_s32   dx_l, dx_r, dy_t, dy_b;
    mlib_s32   edg_sizes[8];
    mlib_status ret;

    MLIB_IMAGE_CHECK(dst);
    MLIB_IMAGE_CHECK(src);
    MLIB_IMAGE_TYPE_EQUAL(dst, src);
    MLIB_IMAGE_HAVE_CHAN(src, 1);
    MLIB_IMAGE_HAVE_CHAN(dst, 1);

    if (colormap == NULL || kernel == NULL)
        return (MLIB_FAILURE);

    img_type = mlib_ImageGetType(src);
    lut_type = mlib_ImageGetLutType(colormap);
    offset = (mlib_s32)mlib_ImageGetLutOffset(colormap);

    if (mlib_ImageGetWidth(src) < m || mlib_ImageGetHeight(src) < n)
        return (MLIB_FAILURE);

    if (((lut_type == MLIB_BYTE) && (scale < 16 || scale > 31)) ||
            ((lut_type == MLIB_SHORT) && (scale < 17 || scale > 32)))
        return (MLIB_FAILURE);

    if (n < MIN_KRNL_HGT || m < MIN_KRNL_WID || dm < 0 || dm > m - 1 ||
            dn < 0 || dn > n - 1)
        return (MLIB_FAILURE);

    ret =
        mlib_ImageClippingMxN(dst_i, src_i, dst_e, src_e, edg_sizes, dst,
                              src, m, n, dm, dn);

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

    dx_l = edg_sizes[0];
    dx_r = edg_sizes[1];
    dy_t = edg_sizes[2];
    dy_b = edg_sizes[3];

    if (dx_l + dx_r + dy_t + dy_b == 0)
        edge = MLIB_EDGE_DST_NO_WRITE;

    func_index = 0;
    if (img_type == MLIB_SHORT) func_index += 1;
    if (lut_type == MLIB_SHORT) func_index += 2;

    if (edge != MLIB_EDGE_SRC_EXTEND) {
        if (mlib_ImageGetWidth(dst_i) >= m &&
                mlib_ImageGetHeight(dst_i) >= n) {
            ret = func_convMxNIndex_nw[func_index](src_i, dst_i,
                                                   m, n, dm, dn, kernel, scale, colormap);
        }

        switch (edge) {
        case MLIB_EDGE_DST_FILL_ZERO:
            mlib_ImageConvClearEdge(dst_e,
                                    dx_l, dx_r, dy_t, dy_b, &offset, 1);
            break;
        case MLIB_EDGE_DST_COPY_SRC:
            mlib_ImageConvCopyEdge(dst_e, src_e,
                                   dx_l, dx_r, dy_t, dy_b, 1);
            break;
        default:
            ret = MLIB_SUCCESS;
            break;
        }
    } else if (mlib_ImageGetWidth(dst_e) > 0 &&
               mlib_ImageGetHeight(dst_e) > 0) {
        /* adjust src_e image */
        mlib_ImageSetSubimage(src_e, src_e, dx_l - dm, dy_t - dn,
                              mlib_ImageGetWidth(src_e), mlib_ImageGetHeight(src_e));

        ret = func_convMxNIndex_ext[func_index](src_e, dst_e, m, n,
                                                dx_l, dx_r, dy_t, dy_b, kernel, scale, colormap);
    }

    return (ret);
}