mlib_status
__mlib_ImageSubsampleAverage_ty_Fp(
    mlib_image *dst,
    const mlib_image *src,
    mlib_d64 xscale,
    mlib_d64 yscale,
    mlib_s32 ybegin)
{
	mlib_type type;

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

	if (!(xscale > 0 && xscale <= 1 && yscale > 0 && yscale <= 1)) {
		return (MLIB_FAILURE);
	}

	type = mlib_ImageGetType(dst);

	switch (type) {
	case MLIB_FLOAT:
		return mlib_ImageSubsampleAverage_F32_main(dst, src, xscale,
		    yscale, ybegin);
	case MLIB_DOUBLE:
		return mlib_ImageSubsampleAverage_D64_main(dst, src, xscale,
		    yscale, ybegin);
	default:
		break;
	}

	return (MLIB_FAILURE);
}
示例#2
0
mlib_status mlib_ImageCopy(mlib_image       *dst,
                           const mlib_image *src)
{
  mlib_s32 s_offset, d_offset;
  mlib_s32 size, s_stride, d_stride;
  mlib_s32 width;                                     /* width in bytes of src and dst */
  mlib_s32 height;                                    /* height in lines of src and dst */
  mlib_u8 *sa, *da;
  mlib_s32 j;

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

  switch (mlib_ImageGetType(dst)) {
    case MLIB_BIT:
      width = mlib_ImageGetWidth(dst) * mlib_ImageGetChannels(dst); /* size in bits */
      height = mlib_ImageGetHeight(src);
      sa = (mlib_u8 *) mlib_ImageGetData(src);
      da = (mlib_u8 *) mlib_ImageGetData(dst);

      if (!mlib_ImageIsNotOneDvector(src) && !mlib_ImageIsNotOneDvector(dst)) {
        size = height * (width >> 3);
        if (!mlib_ImageIsNotAligned8(src) && !mlib_ImageIsNotAligned8(dst) && ((size & 7) == 0)) {

          mlib_c_ImageCopy_a1((TYPE_64BIT *) sa, (TYPE_64BIT *) da, size >> 3);
        }
        else {
示例#3
0
mlib_status
__mlib_ImageCopy(
    mlib_image *dst,
    const mlib_image *src)
{
	mlib_s32 s_offset, d_offset, width, height;
	mlib_s32 size, s_stride, d_stride;
	mlib_u8 *sa, *da;
	mlib_s32 j;

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

	switch (mlib_ImageGetType(dst)) {
	case MLIB_BIT:

		sa = (mlib_u8 *)mlib_ImageGetData(src);
		da = (mlib_u8 *)mlib_ImageGetData(dst);

		width = mlib_ImageGetWidth(src) * mlib_ImageGetChannels(src);
		height = mlib_ImageGetHeight(src);

		if (!mlib_ImageIsNotOneDvector(src) &&
		    !mlib_ImageIsNotOneDvector(dst)) {
			size = height * (width >> 3);
			mlib_ImageCopy_na(sa, da, size);
		} else {
示例#4
0
mlib_status mlib_ImageClippingMxN(mlib_image       *dst_i,
                                  mlib_image       *src_i,
                                  mlib_image       *dst_e,
                                  mlib_image       *src_e,
                                  mlib_s32         *edg_sizes,
                                  const mlib_image *dst,
                                  const mlib_image *src,
                                  mlib_s32         kw,
                                  mlib_s32         kh,
                                  mlib_s32         kw1,
                                  mlib_s32         kh1)
{
  mlib_s32  kw2 = kw - 1 - kw1;
  mlib_s32  kh2 = kh - 1 - kh1;
  mlib_s32  src_wid, src_hgt, dst_wid, dst_hgt;
  mlib_s32  dx, dy, dxd, dxs, dyd, dys, wid_e, hgt_e;
  mlib_s32  dx_l, dx_r, dy_t, dy_b, wid_i, hgt_i;

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

  dst_wid = mlib_ImageGetWidth(dst);
  dst_hgt = mlib_ImageGetHeight(dst);
  src_wid = mlib_ImageGetWidth(src);
  src_hgt = mlib_ImageGetHeight(src);

  /* X clipping */
  dx = src_wid - dst_wid;

  if (dx > 0) {
    dxs = (dx + 1) >> 1;
    dxd = 0;
  } else {
mlib_status
__mlib_ImageColorRGB2HSL_Fp(
    mlib_image *dst,
    const mlib_image *src)
{
/*  check for obvious errors  */
	MLIB_IMAGE_CHECK(src);
	MLIB_IMAGE_CHECK(dst);
	MLIB_IMAGE_TYPE_EQUAL(dst, src);
	MLIB_IMAGE_CHAN_EQUAL(dst, src);
	MLIB_IMAGE_HAVE_CHAN(dst, 3);

	switch (mlib_ImageGetType(dst)) {
	case MLIB_FLOAT:
		mlib_ImageColorRGB2HSL_Fp_F32(dst, src);
		break;
	case MLIB_DOUBLE:
		mlib_ImageColorRGB2HSL_Fp_D64(dst, src);
		break;
/*  discard any other data types  */
	default:
		return (MLIB_FAILURE);
	}

	return (MLIB_SUCCESS);
}
mlib_status
__mlib_ImageCopyMask_Fp(
    mlib_image *dst,
    const mlib_image *src,
    const mlib_image *mask,
    const mlib_d64 *thresh)
{
	mlib_type dtype;
	mlib_s32 slb, mlb, dlb, xsize, ysize, nchan;
	void *sa, *ma, *da;

	MLIB_IMAGE_CHECK(src);
	MLIB_IMAGE_CHECK(dst);
	MLIB_IMAGE_CHECK(mask);

	MLIB_IMAGE_TYPE_EQUAL(src, dst);
	MLIB_IMAGE_TYPE_EQUAL(mask, dst);

	MLIB_IMAGE_CHAN_EQUAL(src, dst);
	MLIB_IMAGE_CHAN_EQUAL(mask, dst);

	MLIB_IMAGE_SIZE_EQUAL(src, dst);
	MLIB_IMAGE_SIZE_EQUAL(mask, dst);

	dtype = mlib_ImageGetType(dst);
	nchan = mlib_ImageGetChannels(dst);
	xsize = mlib_ImageGetWidth(dst);
	ysize = mlib_ImageGetHeight(dst);
	slb = mlib_ImageGetStride(src);
	mlb = mlib_ImageGetStride(mask);
	dlb = mlib_ImageGetStride(dst);
	sa = mlib_ImageGetData(src);
	ma = mlib_ImageGetData(mask);
	da = mlib_ImageGetData(dst);

	if (dtype == MLIB_FLOAT) {
		mlib_ImageCopyMask_Fp_f32(sa, slb, ma, mlb, da, dlb, xsize,
		    ysize, nchan, thresh);
		return (MLIB_SUCCESS);
	} else if (dtype == MLIB_DOUBLE) {
		mlib_ImageCopyMask_Fp_d64(sa, slb, ma, mlb, da, dlb, xsize,
		    ysize, nchan, thresh);
		return (MLIB_SUCCESS);
	} else
		return (MLIB_FAILURE);
}
示例#7
0
mlib_status
__mlib_ImageFlipY_Fp(
    mlib_image *dst,
    const mlib_image *src)
{
	MLIB_IMAGE_CHECK(src);
	MLIB_IMAGE_CHECK(dst);
	MLIB_IMAGE_TYPE_EQUAL(src, dst);
	MLIB_IMAGE_CHAN_EQUAL(src, dst);

	switch (mlib_ImageGetType(src)) {
	case MLIB_FLOAT:
		switch (mlib_ImageGetChannels(src)) {
		case 1:
			mlib_ImageFlipY_S32_1(dst, src);
			break;
		case 2:
			mlib_ImageFlipY_S32_2(dst, src);
			break;
		case 3:
			mlib_ImageFlipY_S32_3(dst, src);
			break;
		case 4:
			mlib_ImageFlipY_S32_4(dst, src);
			break;
		default:
			return (MLIB_FAILURE);
		}

		break;

	case MLIB_DOUBLE:
		switch (mlib_ImageGetChannels(src)) {
		case 1:
			mlib_ImageFlipY_S32_2(dst, src);
			break;
		case 2:
			mlib_ImageFlipY_S32_4(dst, src);
			break;
		case 3:
			mlib_ImageFlipY_D64_3(dst, src);
			break;
		case 4:
			mlib_ImageFlipY_D64_4(dst, src);
			break;
		default:
			return (MLIB_FAILURE);
		}

		break;

	default:
		return (MLIB_FAILURE);
	}

	return (MLIB_SUCCESS);
}
示例#8
0
mlib_status
__mlib_ImageZoomIn2X(
    mlib_image *dst,
    const mlib_image *src,
    mlib_filter filter,
    mlib_edge edge)
{
	mlib_u8 *pdst, *psrc, *pdst_near, *psrc_near, *psrc_beg = NULL;
	mlib_s32 src_height, dst_height, src_width, dst_width, src_stride,
	    dst_stride;
	mlib_s32 type, channels;
	mlib_s32 src_w_beg, src_h_beg, flag = 0;
	mlib_s32 src_width_near, src_height_near, src_w_beg_near,
	    src_h_beg_near;
	mlib_s32 src_width_beg, src_height_beg;

/*  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, channels, src_width, src_height,
	    src_stride, psrc);
	MLIB_IMAGE_GET_ALL_PARAMS(dst, type, channels, dst_width, dst_height,
	    dst_stride, pdst);

	if (type == MLIB_SHORT || type == MLIB_USHORT) {
		channels *= 2;
	} else if (type == MLIB_INT) {
		channels *= 4;
	}

	SIZE_NN(channels);

	src_width_beg = src_width;
	src_height_beg = src_height;

	if (filter == MLIB_NEAREST) {
		pdst = pdst_near;
		psrc = psrc_near;
		src_width = src_width_near;
		src_height = src_height_near;
		src_w_beg = src_w_beg_near;
		src_h_beg = src_h_beg_near;
	} else {
		flag = (dst_height & 1) | ((dst_width & 1) << 1);
		psrc_beg = psrc;

		if (filter == MLIB_BILINEAR) {
			SIZE_BL(channels);
		} else {
			SIZE_BC(channels);
		}
	}

	if (edge == MLIB_EDGE_SRC_PADDED) {
		SIZE_SRC_PADDED(channels);
	}

	if (src_width < 0)
		src_width = 0;

	if (src_height < 0)
		src_height = 0;

	if (type == MLIB_SHORT || type == MLIB_USHORT) {
		channels >>= 1;
		dst_stride >>= 1;
		src_stride >>= 1;
	} else if (type == MLIB_INT) {
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);
		}
	}
}
mlib_status
__mlib_ImageZoomTranslate(
    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)
{
	mlib_type type;
	mlib_s32 nchan, t_ind;
	mlib_status res;
#ifndef	_NO_LONGLONG
	const mlib_s16 *flt_table;
#else
	const mlib_f32 *flt_table;
#endif
	mlib_clipping nearest, current;
	mlib_work_image border, *param = &border;

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

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

	type = mlib_ImageGetType(src);
	nchan = mlib_ImageGetChannels(src);

	switch (type) {
	case MLIB_BIT:
		if (nchan != 1 || filter != MLIB_NEAREST) {
			return (MLIB_FAILURE);
		}
		if (current.width > 0) {
			int s_bitoff = mlib_ImageGetBitOffset(src);
			int d_bitoff = mlib_ImageGetBitOffset(dst);

			return mlib_ImageZoom_BIT_1_Nearest(&border, s_bitoff,
			    d_bitoff);
		}
		return (MLIB_SUCCESS);

	case MLIB_BYTE:
		t_ind = 0;
		break;
	case MLIB_SHORT:
		t_ind = 1;
		break;
	case MLIB_USHORT:
		t_ind = 2;
		break;
	case MLIB_INT:
		t_ind = 3;
		break;
	default:
		return (MLIB_FAILURE);
	}

	if (current.width > 0) {
		switch (filter) {
		case MLIB_NEAREST:
			res = mlib_zoom_nn_funs[border.ind_fun_nn] (&border);
			break;

		case MLIB_BILINEAR:
			if (zoomy < mlib_zoom_bl_level[t_ind]) {
				res =
				    mlib_zoom_bl_lo[4 * t_ind + (nchan -
				    1)] (&border);
			} else {
				res =
				    mlib_zoom_bl_hi[4 * t_ind + (nchan -
				    1)] (&border);
			}
			break;

		case MLIB_BICUBIC:
		case MLIB_BICUBIC2:
			if (type == MLIB_INT) {
				res = mlib_zoom_bc_s32[nchan - 1] (&border);
				break;
			}

#ifndef	_NO_LONGLONG
			if (filter == MLIB_BICUBIC) {
				if (type == MLIB_BYTE) {
					flt_table = mlib_filters_u8_bc;
				} else {
					flt_table = mlib_filters_s16_bc;
				}
			} else {
				if (type == MLIB_BYTE) {
					flt_table = mlib_filters_u8_bc2;
				} else {
					flt_table = mlib_filters_s16_bc2;
				}
			}
#else
			if (filter == MLIB_BICUBIC) {
				if (type == MLIB_BYTE) {
					flt_table = mlib_filters_u8f_bc;
				} else {
					flt_table = mlib_filters_s16f_bc;
				}
			} else {
				if (type == MLIB_BYTE) {
					flt_table = mlib_filters_u8f_bc2;
				} else {
					flt_table = mlib_filters_s16f_bc2;
				}
			}
#endif

			if (zoomy < mlib_zoom_bc_level[t_ind]) {
				res =
				    mlib_zoom_bc_lo[4 * t_ind + (nchan -
				    1)] (&border, flt_table);
			} else {
				res =
				    mlib_zoom_bc_hi[4 * t_ind + (nchan -
				    1)] (&border, flt_table);
			}
			break;

		default:
			return (MLIB_FAILURE);
		}

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

	if (filter == MLIB_NEAREST && edge != MLIB_EDGE_SRC_EXTEND_INDEF) {
		return (MLIB_SUCCESS);
	}

	MLIB_EDGE_RULES;

	return (MLIB_SUCCESS);
}
示例#11
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);
}
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;
			}
示例#13
0
mlib_status
mlib_ImageChannelExtract(mlib_image *dst,
                         mlib_image *src,
                         mlib_s32   cmask)
#endif
{
  const mlib_s32  X8 = 0x7;
  const mlib_s32  X4 = 0x3;
  const mlib_s32  X2 = 0x1;
  const mlib_s32  A8D1   = MLIB_IMAGE_ALIGNED8 | MLIB_IMAGE_ONEDVECTOR;
  const mlib_s32  A8D2X8 = MLIB_IMAGE_ALIGNED8 | MLIB_IMAGE_STRIDE8X | MLIB_IMAGE_WIDTH8X;
  const mlib_s32  A8D2X4 = MLIB_IMAGE_ALIGNED8 | MLIB_IMAGE_STRIDE8X | MLIB_IMAGE_WIDTH4X;
  const mlib_s32  A8D2X2 = MLIB_IMAGE_ALIGNED8 | MLIB_IMAGE_STRIDE8X | MLIB_IMAGE_WIDTH2X;
  void      *sp;            /* pointer for pixel in src */
  void      *dp;            /* pointer for pixel in dst */
  mlib_s32  ncmask = 0;     /* normalized channel mask */
  mlib_s32  channels;       /* number of channels for src */
  mlib_s32  channeld;       /* number of channels for dst */
  mlib_s32  width, height;  /* for src and dst */
  mlib_s32  strides;        /* strides in bytes for src */
  mlib_s32  strided;        /* strides in bytes for dst */
  mlib_s32  flags;
  mlib_s32  flagd;
  mlib_s32  dsize;
  int       delta0 = 0;     /* offset of first selected channel */
  int       count1 = 0;     /* number of channels in first group */
  int       i, bit1count = 0;

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

  channels = mlib_ImageGetChannels(src);
  channeld = mlib_ImageGetChannels(dst);
  width    = mlib_ImageGetWidth(src);
  height   = mlib_ImageGetHeight(src);
  strides  = mlib_ImageGetStride(src);
  strided  = mlib_ImageGetStride(dst);
  sp       = mlib_ImageGetData(src);
  dp       = mlib_ImageGetData(dst);
  flags    = mlib_ImageGetFlags(src);
  flagd    = mlib_ImageGetFlags(dst);
  dsize    = width * height;

  /* normalize the cmask, and count the number of bit with value 1 */
  for (i = (channels - 1); i >= 0; i--) {
    if (((cmask & (1 << i)) != 0) && (bit1count < channeld)) {
      ncmask += (1 << i);
      bit1count++;
    }
  }

  /* do not support the cases in which the number of selected channels is
   * less than the nubmber of channels in the destination image */
  if (bit1count < channeld) {
    return MLIB_FAILURE;
  }

  if (channels == channeld) {
#ifdef MLIB_TEST
    mlib_v_ImageCopy(dst, src);
#else
    mlib_ImageCopy(dst, src);
#endif
    return MLIB_SUCCESS;
  }

  switch (mlib_ImageGetType(src)) {
    case MLIB_BYTE:
      if (channeld == 1) {
        switch (channels) {
          case 2:
            if (((flags & A8D1) == 0) &&
                ((flagd & A8D1) == 0) &&
                ((dsize & X8)   == 0)) {
              mlib_v_ImageChannelExtract_U8_21_A8D1X8((mlib_u8 *)sp,
                                                      (mlib_u8 *)dp,
                                                      dsize,
                                                      ncmask);
            }
            else if (((flags & A8D2X8) == 0) &&
                     ((flagd & A8D2X8) == 0)) {
              mlib_v_ImageChannelExtract_U8_21_A8D2X8((mlib_u8 *)sp, strides,
                                                      (mlib_u8 *)dp, strided,
                                                      width, height,
                                                      ncmask);
            }
            else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
                     ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
              mlib_v_ImageChannelExtract_U8_21_D1((mlib_u8 *)sp,
                                                  (mlib_u8 *)dp,
                                                  dsize,
                                                  ncmask);
            }
            else {
              mlib_v_ImageChannelExtract_U8_21((mlib_u8 *)sp, strides,
                                               (mlib_u8 *)dp, strided,
                                               width, height,
                                               ncmask);
            }
            return MLIB_SUCCESS;

          case 3:
            if (((flags & A8D1) == 0) &&
                ((flagd & A8D1) == 0) &&
                ((dsize & X8)   == 0)) {
              mlib_v_ImageChannelExtract_U8_31_A8D1X8((mlib_u8 *)sp,
                                                      (mlib_u8 *)dp,
                                                      dsize,
                                                      ncmask);
            }
            else if (((flags & A8D2X8) == 0) &&
                     ((flagd & A8D2X8) == 0)) {
              mlib_v_ImageChannelExtract_U8_31_A8D2X8((mlib_u8 *)sp, strides,
                                                      (mlib_u8 *)dp, strided,
                                                      width, height,
                                                      ncmask);
            }
            else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
                     ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
              mlib_v_ImageChannelExtract_U8_31_D1((mlib_u8 *)sp,
                                                  (mlib_u8 *)dp,
                                                  dsize,
                                                  ncmask);
            }
            else {
              mlib_v_ImageChannelExtract_U8_31((mlib_u8 *)sp, strides,
                                               (mlib_u8 *)dp, strided,
                                               width, height,
                                               ncmask);
            }
            return MLIB_SUCCESS;

          case 4:
            if (((flags & A8D1) == 0) &&
                ((flagd & A8D1) == 0) &&
                ((dsize & X8)   == 0)) {
              mlib_v_ImageChannelExtract_U8_41_A8D1X8((mlib_u8 *)sp,
                                                      (mlib_u8 *)dp,
                                                      dsize,
                                                      ncmask);
            }
            else if (((flags & A8D2X8) == 0) &&
                     ((flagd & A8D2X8) == 0)) {
              mlib_v_ImageChannelExtract_U8_41_A8D2X8((mlib_u8 *)sp, strides,
                                                      (mlib_u8 *)dp, strided,
                                                      width, height,
                                                      ncmask);
            }
            else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
                     ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
              mlib_v_ImageChannelExtract_U8_41_D1((mlib_u8 *)sp,
                                                  (mlib_u8 *)dp,
                                                  dsize,
                                                  ncmask);
            }
            else {
              mlib_v_ImageChannelExtract_U8_41((mlib_u8 *)sp, strides,
                                               (mlib_u8 *)dp, strided,
                                               width, height,
                                               ncmask);
            }
            return MLIB_SUCCESS;

          default:
            return MLIB_FAILURE;
        }
      }
      else if ((channels == 4) && (channeld == 3) && (ncmask == 7)) {
        if (((flags & A8D1) == 0) &&
            ((flagd & A8D1) == 0) &&
            ((dsize & X8)   == 0)) {
          mlib_v_ImageChannelExtract_U8_43R_A8D1X8((mlib_u8 *)sp,
                                                   (mlib_u8 *)dp,
                                                   dsize);
        }
        else if (((flags & A8D2X8) == 0) &&
                 ((flagd & A8D2X8) == 0)) {
          mlib_v_ImageChannelExtract_U8_43R_A8D2X8((mlib_u8 *)sp, strides,
                                                   (mlib_u8 *)dp, strided,
                                                   width, height);
        }
        else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
                 ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
          mlib_v_ImageChannelExtract_U8_43R_D1((mlib_u8 *)sp,
                                               (mlib_u8 *)dp,
                                               dsize);
        }
        else {
          mlib_v_ImageChannelExtract_U8_43R((mlib_u8 *)sp, strides,
                                            (mlib_u8 *)dp, strided,
                                            width, height);
        }
        return MLIB_SUCCESS;
      }
      else if ((channels == 4) && (channeld == 3) && (ncmask == 14)) {
        if (((flags & A8D1) == 0) &&
            ((flagd & A8D1) == 0) &&
            ((dsize & X8)   == 0)) {
          mlib_v_ImageChannelExtract_U8_43L_A8D1X8((mlib_u8 *)sp,
                                                   (mlib_u8 *)dp,
                                                   dsize);
        }
        else if (((flags & A8D2X8) == 0) &&
                 ((flagd & A8D2X8) == 0)) {
          mlib_v_ImageChannelExtract_U8_43L_A8D2X8((mlib_u8 *)sp, strides,
                                                   (mlib_u8 *)dp, strided,
                                                   width, height);
        }
        else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
                 ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
          mlib_v_ImageChannelExtract_U8_43L_D1((mlib_u8 *)sp,
                                               (mlib_u8 *)dp,
                                               dsize);
        }
        else {
          mlib_v_ImageChannelExtract_U8_43L((mlib_u8 *)sp, strides,
                                            (mlib_u8 *)dp, strided,
                                            width, height);
        }
        return MLIB_SUCCESS;
      }
      break;

    case MLIB_SHORT:
      if (channeld == 1) {
        switch (channels) {
          case 2:
            if (((flags & A8D1) == 0) &&
                ((flagd & A8D1) == 0) &&
                ((dsize & X4)   == 0)) {
              mlib_v_ImageChannelExtract_S16_21_A8D1X4((mlib_s16 *)sp,
                                                       (mlib_s16 *)dp,
                                                       dsize,
                                                       ncmask);
            }
            else if (((flags & A8D2X4) == 0) &&
                     ((flagd & A8D2X4) == 0)) {
              mlib_v_ImageChannelExtract_S16_21_A8D2X4((mlib_s16 *)sp, strides,
                                                       (mlib_s16 *)dp, strided,
                                                       width, height,
                                                       ncmask);
            }
            else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
                     ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
              mlib_v_ImageChannelExtract_S16_21_D1((mlib_s16 *)sp,
                                                   (mlib_s16 *)dp,
                                                   dsize,
                                                   ncmask);
            }
            else {
              mlib_v_ImageChannelExtract_S16_21((mlib_s16 *)sp, strides,
                                                (mlib_s16 *)dp, strided,
                                                width, height,
                                                ncmask);
            }
            return MLIB_SUCCESS;

          case 3:
            if (((flags & A8D1) == 0) &&
                ((flagd & A8D1) == 0) &&
                ((dsize & X4)   == 0)) {
              mlib_v_ImageChannelExtract_S16_31_A8D1X4((mlib_s16 *)sp,
                                                       (mlib_s16 *)dp,
                                                       dsize,
                                                       ncmask);
            }
            else if (((flags & A8D2X4) == 0) &&
                     ((flagd & A8D2X4) == 0)) {
              mlib_v_ImageChannelExtract_S16_31_A8D2X4((mlib_s16 *)sp, strides,
                                                       (mlib_s16 *)dp, strided,
                                                       width, height,
                                                       ncmask);
            }
            else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
                     ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
              mlib_v_ImageChannelExtract_S16_31_D1((mlib_s16 *)sp,
                                                   (mlib_s16 *)dp,
                                                   dsize,
                                                   ncmask);
            }
            else {
              mlib_v_ImageChannelExtract_S16_31((mlib_s16 *)sp, strides,
                                                (mlib_s16 *)dp, strided,
                                                width, height,
                                                ncmask);
            }
            return MLIB_SUCCESS;

          case 4:
            if (((flags & A8D1) == 0) &&
                ((flagd & A8D1) == 0) &&
                ((dsize & X4)   == 0)) {
              mlib_v_ImageChannelExtract_S16_41_A8D1X4((mlib_s16 *)sp,
                                                       (mlib_s16 *)dp,
                                                       dsize,
                                                       ncmask);
            }
            else if (((flags & A8D2X4) == 0) &&
                     ((flagd & A8D2X4) == 0)) {
              mlib_v_ImageChannelExtract_S16_41_A8D2X4((mlib_s16 *)sp, strides,
                                                       (mlib_s16 *)dp, strided,
                                                       width, height,
                                                       ncmask);
            }
            else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
                     ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
              mlib_v_ImageChannelExtract_S16_41_D1((mlib_s16 *)sp,
                                                   (mlib_s16 *)dp,
                                                   dsize,
                                                   ncmask);
            }
            else {
              mlib_v_ImageChannelExtract_S16_41((mlib_s16 *)sp, strides,
                                                (mlib_s16 *)dp, strided,
                                                width, height,
                                                ncmask);
            }
            return MLIB_SUCCESS;
          default:
            return MLIB_FAILURE;
        }
      }
      else if ((channels == 4) && (channeld == 3) && (ncmask == 7)) {
        if (((flags & A8D1) == 0) &&
            ((flagd & A8D1) == 0) &&
            ((dsize & X4)   == 0)) {
          mlib_v_ImageChannelExtract_S16_43R_A8D1X4((mlib_s16 *)sp,
                                                    (mlib_s16 *)dp,
                                                    dsize);
        }
        else if (((flags & A8D2X4) == 0) &&
                 ((flagd & A8D2X4) == 0)) {
          mlib_v_ImageChannelExtract_S16_43R_A8D2X4((mlib_s16 *)sp, strides,
                                                    (mlib_s16 *)dp, strided,
                                                    width, height);
        }
        else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
                 ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
          mlib_v_ImageChannelExtract_S16_43R_D1((mlib_s16 *)sp,
                                                (mlib_s16 *)dp,
                                                dsize);
        }
        else {
          mlib_v_ImageChannelExtract_S16_43R((mlib_s16 *)sp, strides,
                                             (mlib_s16 *)dp, strided,
                                             width, height);
        }
        return MLIB_SUCCESS;
      }
      else if ((channels == 4) && (channeld == 3) && (ncmask == 14)) {
        if (((flags & A8D1) == 0) &&
            ((flagd & A8D1) == 0) &&
            ((dsize & X4)   == 0)) {
          mlib_v_ImageChannelExtract_S16_43L_A8D1X4((mlib_s16 *)sp,
                                                    (mlib_s16 *)dp,
                                                    dsize);
        }
        else if (((flags & A8D2X4) == 0) &&
                 ((flagd & A8D2X4) == 0)) {
          mlib_v_ImageChannelExtract_S16_43L_A8D2X4((mlib_s16 *)sp, strides,
                                                    (mlib_s16 *)dp, strided,
                                                    width, height);
        }
        else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
                 ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
          mlib_v_ImageChannelExtract_S16_43L_D1((mlib_s16 *)sp,
                                                (mlib_s16 *)dp,
                                                dsize);
        }
        else {
          mlib_v_ImageChannelExtract_S16_43L((mlib_s16 *)sp, strides,
                                             (mlib_s16 *)dp, strided,
                                             width, height);
        }
        return MLIB_SUCCESS;
      }
      break;

  }

/***************************************************************/
  /* From C version */

  for (i = (channels - 1); i >= 0; i--) {
    if (!(ncmask & (1 << i))) delta0++;
    else break;
  }
  for (; i >= 0; i--) {
    if (ncmask & (1 << i)) count1++;
    else break;
  }

  switch (mlib_ImageGetType(src)) {
    case MLIB_BYTE:
      {
        mlib_u8 *sl = (mlib_u8 *)sp + delta0;
        mlib_u8 *dl = (mlib_u8 *)dp;

        switch (channels*10 + channeld) {
          case 32:
            mlib_v_ImageChannelExtract_U8_3_2(sl, strides, dl, strided, width, height, count1);
            return MLIB_SUCCESS;

          case 42:
            if (ncmask == 0xA || ncmask == 0x5) { /* mask 1010 or 0101 */
              mlib_v_ImageChannelExtract_U8_2_1(sl, strides, dl, strided, 2*width, height);
              return MLIB_SUCCESS;
            }
            mlib_v_ImageChannelExtract_U8_4_2(sl, strides, dl, strided, width, height, count1);
            return MLIB_SUCCESS;

          case 43:
            mlib_v_ImageChannelExtract_U8((mlib_u8 *)sp, strides,
                                          (mlib_u8 *)dp, strided,
                                          channels, channeld,
                                          width, height,
                                          ncmask);
            return MLIB_SUCCESS;

          default: return MLIB_FAILURE;
        }
      }

    case MLIB_SHORT:
      mlib_v_ImageChannelExtract_S16((mlib_u16 *)sp, strides,
                                     (mlib_u16 *)dp, strided,
                                     channels,  channeld,
                                     width, height,
                                     ncmask);
      break;

    case MLIB_INT:
    case MLIB_FLOAT:
      {
        mlib_f32 *sl = (mlib_f32 *)sp + delta0;
        mlib_f32 *dl = (mlib_f32 *)dp;
        strides /= 4;
        strided /= 4;

        switch (channels*10 + channeld) {
          case 21:
            mlib_v_ImageChannelExtract_32_2_1(sl, strides, dl, strided, width, height);
            return MLIB_SUCCESS;

          case 31:
            mlib_v_ImageChannelExtract_32_3_1(sl, strides, dl, strided, width, height);
            return MLIB_SUCCESS;

          case 32:
            mlib_v_ImageChannelExtract_32_3_2(sl, strides, dl, strided, width, height, count1);
            return MLIB_SUCCESS;

          case 41:
            mlib_v_ImageChannelExtract_32_4_1(sl, strides, dl, strided, width, height);
            return MLIB_SUCCESS;

          case 42:
            if (ncmask == 0xA || ncmask == 0x5) { /* mask 1010 or 0101 */
              mlib_v_ImageChannelExtract_32_2_1(sl, strides, dl, strided, 2*width, height);
            } else {
              mlib_v_ImageChannelExtract_32_4_2(sl, strides, dl, strided, width, height, count1);
            }
            return MLIB_SUCCESS;

          case 43:
            mlib_v_ImageChannelExtract_32_4_3(sl, strides, dl, strided, width, height, count1);
            return MLIB_SUCCESS;

          default:
            return MLIB_FAILURE;
        }
      }
    case MLIB_DOUBLE:
      mlib_v_ImageChannelExtract_D64((mlib_d64 *)sp, strides,
                                     (mlib_d64 *)dp, strided,
                                     channels,  channeld,
                                     width, height,
                                     ncmask);
      break;

    case MLIB_BIT:
    default:
      return MLIB_FAILURE;  /* MLIB_BIT is not supported here */
  }

  return MLIB_SUCCESS;
}
mlib_status
__mlib_ImageZoomTranslate_Fp(
    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)
{
	mlib_type type;
	mlib_s32 nchan, t_ind;
	mlib_status res;
	mlib_clipping nearest, current;
	mlib_work_image border;

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

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

	type = mlib_ImageGetType(src);
	nchan = mlib_ImageGetChannels(src);

	if (type == MLIB_FLOAT) {
		t_ind = 0;
	} else if (type == MLIB_DOUBLE) {
		t_ind = 1;
	} else {
		return (MLIB_FAILURE);
	}

	if (current.width > 0) {
		switch (filter) {
		case MLIB_NEAREST:
			res =
			    mlib_zoom_nn_funs[border.ind_fun_nn -
			    2 * 4] (&border);
			break;

		case MLIB_BILINEAR:
			if (zoomy < 1.0) {
				res =
				    mlib_zoom_bl_lo[4 * t_ind + (nchan -
				    1)] (&border);
			} else {
				res =
				    mlib_zoom_bl_hi[4 * t_ind + (nchan -
				    1)] (&border);
			}
			break;

		case MLIB_BICUBIC:
		case MLIB_BICUBIC2:
			res =
			    mlib_zoom_bc_funs[4 * t_ind + (nchan -
			    1)] (&border);
			break;

		default:
			return (MLIB_FAILURE);
		}

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

	if (filter == MLIB_NEAREST && edge != MLIB_EDGE_SRC_EXTEND_INDEF) {
		return (MLIB_SUCCESS);
	}

	switch (edge) {

/* handle edge condition of image */
	case MLIB_EDGE_DST_FILL_ZERO:

		switch (mlib_ImageGetType(src)) {
		case MLIB_FLOAT:
			mlib_ImageZoomZeroEdge_F32(&border);
			break;

		case MLIB_DOUBLE:
			mlib_ImageZoomZeroEdge_D64(&border);
			break;

		default:
			return (MLIB_FAILURE);
		}

		break;

	case MLIB_EDGE_OP_NEAREST:

		switch (mlib_ImageGetType(src)) {
		case MLIB_FLOAT:
			mlib_ImageZoomUpNearest_F32(&border);
			break;

		case MLIB_DOUBLE:
			mlib_ImageZoomUpNearest_D64(&border);
			break;

		default:
			return (MLIB_FAILURE);
		}

		break;

	case MLIB_EDGE_SRC_EXTEND:
	case MLIB_EDGE_SRC_EXTEND_INDEF:

		switch (mlib_ImageGetType(src)) {
		case MLIB_FLOAT:
			switch (filter) {
			case MLIB_NEAREST:
				mlib_ImageZoomExtend_F32_Nearest(&border);
				break;

			case MLIB_BILINEAR:
				mlib_ImageZoomExtend_F32_Bilinear(&border);
				break;

			case MLIB_BICUBIC:
				mlib_ImageZoomExtend_F32_Bicubic(&border);
				break;

			case MLIB_BICUBIC2:
				mlib_ImageZoomExtend_F32_Bicubic2(&border);
				break;
			}

			break;

		case MLIB_DOUBLE:
			switch (filter) {
			case MLIB_NEAREST:
				mlib_ImageZoomExtend_D64_Nearest(&border);
				break;

			case MLIB_BILINEAR:
				mlib_ImageZoomExtend_D64_Bilinear(&border);
				break;

			case MLIB_BICUBIC:
				mlib_ImageZoomExtend_D64_Bicubic(&border);
				break;

			case MLIB_BICUBIC2:
				mlib_ImageZoomExtend_D64_Bicubic2(&border);
				break;
			}

			break;
		default:
			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:
	default:
		return (MLIB_SUCCESS);
	}

	return (MLIB_SUCCESS);
}
示例#15
0
mlib_status
__mlib_ImageCopy(
    mlib_image *dst,
    const mlib_image *src)
{
/* start point in source */
	mlib_u8 *sa;

/* start points in destination */
	mlib_u8 *da;

/* width in bytes of src and dst */
	mlib_s32 width;

/* height in lines of src and dst */
	mlib_s32 height;

/* bit offset of src */
	mlib_s32 s_offset;

/* bit offset of dst */
	mlib_s32 d_offset;

/* stride in bytes in src */
	mlib_s32 stride;

/* stride in bytes in dst */
	mlib_s32 dstride;

/* indices for x, y */
	mlib_s32 i, j;
	mlib_s32 size;

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

	width = mlib_ImageGetWidth(dst) * mlib_ImageGetChannels(dst);
	height = mlib_ImageGetHeight(dst);
	sa = (mlib_u8 *)mlib_ImageGetData(src);
	da = (mlib_u8 *)mlib_ImageGetData(dst);

	switch (mlib_ImageGetType(dst)) {
	case MLIB_BIT:

		if (!mlib_ImageIsNotOneDvector(src) &&
		    !mlib_ImageIsNotOneDvector(dst)) {
			size = height * (width >> 3);

			if ((size & 0x3f) == 0 &&
			    !mlib_ImageIsNotAligned64(src) &&
			    !mlib_ImageIsNotAligned64(dst)) {

				mlib_v_ImageCopy_blk(sa, da, size);
				return (MLIB_SUCCESS);
			}

			if (!mlib_ImageIsNotAligned8(src) &&
			    !mlib_ImageIsNotAligned8(dst) &&
			    ((size & 7) == 0)) {

				mlib_v_ImageCopy_a1((mlib_d64 *)sa,
				    (mlib_d64 *)da, size >> 3);
			} else {
示例#16
0
mlib_status
__mlib_ImageChannelCopy(
    mlib_image *dst,
    const mlib_image *src,
    mlib_s32 cmask)
{
	mlib_type dtype;
	mlib_s32 src_stride, dst_stride, src_width, src_height, nchannels;
	mlib_s32 mask;
	void *sa, *da;

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

	dtype = mlib_ImageGetType(src);
	nchannels = mlib_ImageGetChannels(src);
	src_stride = mlib_ImageGetStride(src);
	dst_stride = mlib_ImageGetStride(dst);
	src_height = mlib_ImageGetHeight(src);
	src_width = mlib_ImageGetWidth(src);
	sa = mlib_ImageGetData(src);
	da = mlib_ImageGetData(dst);

	mask = cmask & ((1 << nchannels) - 1);

	if (!mask)
		return (MLIB_SUCCESS);

	if (((nchannels == 1) && (cmask == 1)) ||
	    ((nchannels == 2) && (cmask == 3)) ||
	    ((nchannels == 3) && (cmask == 7)) ||
	    ((nchannels == 4) && (cmask == 15))) {
		return (__mlib_ImageCopy(dst, src));
	} else {
		mlib_s32 src_width_nchannels = src_width * nchannels;

		if (src_width_nchannels == src_stride &&
		    src_width_nchannels == dst_stride) {
			src_width *= src_height;
			src_height = 1;
		}

		if (dtype == MLIB_BYTE) {
			if (nchannels == 3) {
				mlib_c_ImageChannelCopy_u8_3((mlib_u8 *)sa,
				    src_stride, (mlib_u8 *)da, dst_stride,
				    src_width, src_height, mask);
				return (MLIB_SUCCESS);
			} else {
				mlib_c_ImageChannelCopy_u8_24((mlib_u8 *)sa,
				    src_stride, (mlib_u8 *)da, dst_stride,
				    nchannels, src_width, src_height, mask);
				return (MLIB_SUCCESS);
			}
		} else if ((dtype == MLIB_SHORT) || (dtype == MLIB_USHORT)) {

			if (nchannels == 4) {
				mlib_c_ImageChannelCopy_s16_4((mlib_s16 *)sa,
				    src_stride, (mlib_s16 *)da, dst_stride,
				    src_width, src_height, mask);
				return (MLIB_SUCCESS);
			} else if (nchannels == 3) {
				mlib_c_ImageChannelCopy_s16_3((mlib_s16 *)sa,
				    src_stride, (mlib_s16 *)da, dst_stride,
				    src_width, src_height, mask);
				return (MLIB_SUCCESS);
			} else if (nchannels == 2) {
				mlib_c_ImageChannelCopy_s16_2((mlib_s16 *)sa,
				    src_stride, (mlib_s16 *)da, dst_stride,
				    src_width, src_height, mask);
				return (MLIB_SUCCESS);
			}

			return (MLIB_SUCCESS);
		} else if ((dtype == MLIB_INT) || (dtype == MLIB_FLOAT)) {
			mlib_c_ImageChannelCopy_s32((mlib_s32 *)sa, src_stride,
			    (mlib_s32 *)da, dst_stride, nchannels, src_width,
			    src_height, mask);
			return (MLIB_SUCCESS);
		} else if (dtype == MLIB_DOUBLE) {
			mlib_c_ImageChannelCopy_d64((mlib_d64 *)sa, src_stride,
			    (mlib_d64 *)da, dst_stride, nchannels, src_width,
			    src_height, mask);
			return (MLIB_SUCCESS);
		} else {
			return (MLIB_FAILURE);
		}
	}
}
示例#17
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);
}
mlib_status
__mlib_ImagePolynomialWarp(
    mlib_image *dst,
    const mlib_image *src,
    const mlib_d64 *xCoeffs,
    const mlib_d64 *yCoeffs,
    mlib_s32 n,
    mlib_d64 preShiftX,
    mlib_d64 preShiftY,
    mlib_d64 postShiftX,
    mlib_d64 postShiftY,
    mlib_d64 preScaleX,
    mlib_d64 preScaleY,
    mlib_d64 postScaleX,
    mlib_d64 postScaleY,
    mlib_filter filter,
    mlib_edge edge)
{
    mlib_IPWClipLine array_func_clip[3] = {
        mlib_ImagePolynomialWarpClipLine_0,
        mlib_ImagePolynomialWarpClipLine_1,
        mlib_ImagePolynomialWarpClipLine_2
    };
    mlib_IPWFCall array_func[12][4] = {
        /* nearest neighbor */
        /* U8  */
        {TIN(NN_U8_1), TIN(NN_U8_2), TIN(NN_U8_3), TIN(NN_U8_4)},
        /* S16 */
        {TIN(NN_S16_1), TIN(NN_S16_2), TIN(NN_S16_3), TIN(NN_S16_4)},
        /* U16 */
        {TIN(NN_S16_1), TIN(NN_S16_2), TIN(NN_S16_3), TIN(NN_S16_4)},
        /* S32 */
        {TIN(NN_S32_1), TIN(NN_S32_2), TIN(NN_S32_3), TIN(NN_S32_4)},

        /* bilinear */
        /* U8  */
        {TIN(BL_U8_1), TIN(BL_U8_2), TIN(BL_U8_3), TIN(BL_U8_4)},
        /* S16 */
        {TIN(BL_S16_1), TIN(BL_S16_2), TIN(BL_S16_3), TIN(BL_S16_4)},
        /* U16 */
        {TIN(BL_U16_1), TIN(BL_U16_2), TIN(BL_U16_3), TIN(BL_U16_4)},
        /* S32 */
        {TIN(BL_S32_1), TIN(BL_S32_2), TIN(BL_S32_3), TIN(BL_S32_4)},

        /* bicubic and bicubic2 */
        /* U8  */
        {TIN(BC_U8_1), TIN(BC_U8_2), TIN(BC_U8_3), TIN(BC_U8_4)},
        /* S16 */
        {TIN(BC_S16_1), TIN(BC_S16_2), TIN(BC_S16_3), TIN(BC_S16_4)},
        /* U16 */
        {TIN(BC_U16_1), TIN(BC_U16_2), TIN(BC_U16_3), TIN(BC_U16_4)},
        /* S32 */
        {TIN(BC_S32_1), TIN(BC_S32_2), TIN(BC_S32_3), TIN(BC_S32_4)}
    };

    void *memory = 0;
    mlib_d64 x = 0.5 + preShiftY;
    mlib_d64 border;
    mlib_d64 *xCoeffs_new;
    mlib_d64 *yCoeffs_new;
    mlib_s32 i, len, pos;
    mlib_s32 k = (n + 1) * (n + 2) / 2;
    mlib_s32 channels;
    mlib_u8 *dstData;
    mlib_u8 *srcData;
    const mlib_u8 **lineAddr;
    mlib_type type;
    mlib_PWS pws;
    mlib_IPWClipLine func_clip = NULL;
    mlib_IPWFCall func;

    if (n < 0)
        return (MLIB_FAILURE);

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

    channels = mlib_ImageGetChannels(src);
    dstData = mlib_ImageGetData(dst);
    srcData = mlib_ImageGetData(src);
    type = mlib_ImageGetType(src);

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

    if (n == 0) {
        return mlib_ImagePolynomialWarp_0(dst, src,
                                          xCoeffs, yCoeffs,
                                          postShiftX, postShiftY, postScaleX, postScaleY,
                                          filter, edge);
    }

    if (n == 1) {
        return mlib_ImagePolynomialWarp_1(dst, src,
                                          xCoeffs, yCoeffs,
                                          preShiftX, preShiftY, postShiftX, postShiftY,
                                          preScaleX, preScaleY, postScaleX, postScaleY, filter, edge);
    }

    len = mlib_ImageGetWidth(dst) + 1;
    memory = __mlib_malloc((sizeof (mlib_s32) * 3 +
                            sizeof (mlib_d64) * 2 +
                            sizeof (mlib_d64) * 8) * len +
                           sizeof (void *) * mlib_ImageGetHeight(src));

    if (!memory)
        return (MLIB_FAILURE);

    pws.buffer = memory;

    pws.dsrc_x = (mlib_d64 *)pws.buffer + 8 * mlib_ImageGetWidth(dst);
    pws.dsrc_y = (mlib_d64 *)pws.dsrc_x + mlib_ImageGetWidth(dst);
    lineAddr = (void *)((mlib_d64 *)pws.dsrc_y + mlib_ImageGetWidth(dst));
    pws.src_x = (void *)(lineAddr + mlib_ImageGetHeight(src));
    pws.src_y = (mlib_s32 *)pws.src_x + len;
    pws.dst_x = (mlib_s32 *)pws.src_y + len;

    pws.flags = 0;
    pws.filter_table = (void *)mlib_filters_u8f_bc;

    if (type == MLIB_SHORT || type == MLIB_USHORT)
        pws.filter_table = (void *)mlib_filters_s16f_bc;

    if (filter == MLIB_BICUBIC2) {
        pws.flags = 1;
        filter = MLIB_BICUBIC;
        pws.filter_table = (void *)mlib_filters_u8f_bc2;

        if (type == MLIB_SHORT || type == MLIB_USHORT)
            pws.filter_table = (void *)mlib_filters_s16f_bc2;
    }

    border =
        (filter == MLIB_BILINEAR) ? 0.5 : ((filter ==
                                            MLIB_BICUBIC) ? 1.5 : 0);

    pws.SrcStartX = border;
    pws.SrcStartY = border;
    pws.SrcStopX = mlib_ImageGetWidth(src) - border;
    pws.SrcStopY = mlib_ImageGetHeight(src) - border;

    if (edge == MLIB_EDGE_SRC_PADDED) {
        mlib_u8 *paddings = mlib_ImageGetPaddings(src);
        mlib_s32 width = mlib_ImageGetWidth(src) - paddings[2];
        mlib_s32 height = mlib_ImageGetHeight(src) - paddings[3];

        if (paddings[0] > pws.SrcStartX)
            pws.SrcStartX = paddings[0];
        if (paddings[1] > pws.SrcStartY)
            pws.SrcStartY = paddings[1];
        if (width < pws.SrcStopX)
            pws.SrcStopX = width;
        if (height < pws.SrcStopY)
            pws.SrcStopY = height;
    }

    xCoeffs_new = mlib_ImagePolynimialWarpCoeffsPrepare(xCoeffs, yCoeffs,
                  preScaleX, preScaleY,
                  postScaleX, postScaleY, postShiftX, postShiftY, n);

    if (!xCoeffs_new) {
        __mlib_free(memory);
        return (MLIB_FAILURE);
    }

    yCoeffs_new = xCoeffs_new + k;

    pws.xCoeffs = xCoeffs_new;
    pws.yCoeffs = yCoeffs_new;
    pws.degree = n - 2;

    if (n < 6) {
        mlib_ImagePolynomialWarp_2_5(dst, src,
                                     lineAddr, &pws,
                                     xCoeffs_new, yCoeffs_new,
                                     preShiftX, preShiftY, filter, edge);
        FREE_MEMORY;
        return (MLIB_SUCCESS);
    }

    pos = mlib_ImageGetHeight(src);
    for (i = 0; i < pos; i++) {
        lineAddr[i] = srcData;
        srcData += mlib_ImageGetStride(src);
    }

    if (filter == MLIB_NEAREST) {
        func_clip = array_func_clip[0];
    } else {
        if (filter == MLIB_BILINEAR)
            func_clip = array_func_clip[1];
        else {
            if (filter == MLIB_BICUBIC) {
                if (type == MLIB_INT)
                    func_clip = array_func_clip[1];
                else
                    func_clip = array_func_clip[2];
            }
        }
    }

    pos =
        (filter == MLIB_NEAREST) ? 0 : ((filter == MLIB_BILINEAR) ? 4 : 8);
    pos +=
        (type == MLIB_BYTE) ? 0 : ((type == MLIB_SHORT) ? 1 : ((type ==
                                   MLIB_USHORT) ? 2 : 3));

    func = array_func[pos][channels - 1];

    for (i = 0; i < mlib_ImageGetHeight(dst); i++) {

        len = func_clip(&pws, x, preShiftX, mlib_ImageGetWidth(dst), n);

        func(dstData, lineAddr, &pws, len);
        dstData += mlib_ImageGetStride(dst);

        x += 1.0;
    }

    FREE_MEMORY;
    return (MLIB_SUCCESS);
}
示例#19
0
mlib_status
__mlib_ImageRotate180_Fp(
    mlib_image *dst,
    const mlib_image *src)
{

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

	switch (mlib_ImageGetType(src)) {

/*  handle MLIB_FLOAT data type of image  */
	case MLIB_FLOAT:
		switch (mlib_ImageGetChannels(src)) {
		case 1:
			mlib_s_ImageRotate180_S32_1(dst, src);
			break;
		case 2:
			mlib_s_ImageRotate180_D64_1(dst, src);
			break;
		case 3:
			mlib_s_ImageRotate180_S32_3(dst, src);
			break;
		case 4:
			mlib_s_ImageRotate180_D64_2(dst, src);
			break;
		default:
			return (MLIB_FAILURE);
		}
		break;

/*  handle MLIB_DOUBLE data type of image  */
	case MLIB_DOUBLE:
		switch (mlib_ImageGetChannels(src)) {
		case 1:
			mlib_s_ImageRotate180_D64_1(dst, src);
			break;
		case 2:
			mlib_s_ImageRotate180_D64_2(dst, src);
			break;
		case 3:
			mlib_s_ImageRotate180_D64_3(dst, src);
			break;
		case 4:
			mlib_s_ImageRotate180_D64_4(dst, src);
			break;
		default:
			return (MLIB_FAILURE);
		}
		break;

/*  discard any other data types  */
	default:
		return (MLIB_FAILURE);

	}
	return (MLIB_SUCCESS);
}
示例#20
0
mlib_status mlib_ImageAffine_alltypes(mlib_image       *dst,
                                      const mlib_image *src,
                                      const mlib_d64   *mtx,
                                      mlib_filter      filter,
                                      mlib_edge        edge,
                                      const void       *colormap)
{
  mlib_affine_param param[1];
  mlib_status res;
  mlib_type type;
  mlib_s32 nchan, t_ind, kw, kw1;
  mlib_addr align;
  mlib_d64 buff_lcl[BUFF_SIZE / 8];
  mlib_u8 **lineAddr = NULL;

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

  type = mlib_ImageGetType(dst);
  nchan = mlib_ImageGetChannels(dst);

  switch (filter) {
    case MLIB_NEAREST:
      kw = 1;
      kw1 = 0;
      break;

    case MLIB_BILINEAR:
      kw = 2;
      kw1 = 0;
      break;

    case MLIB_BICUBIC:
    case MLIB_BICUBIC2:
      kw = 4;
      kw1 = 1;
      break;

    default:
      return MLIB_FAILURE;
  }

  STORE_PARAM(param, lineAddr);
  STORE_PARAM(param, filter);

  res = mlib_AffineEdges(param, dst, src, buff_lcl, BUFF_SIZE,
                         kw, kw, kw1, kw1, edge, mtx, MLIB_SHIFT, MLIB_SHIFT);

  if (res != MLIB_SUCCESS)
    return res;

  lineAddr = param->lineAddr;

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

  if (colormap != NULL && filter != MLIB_NEAREST) {
    if (t_ind != 0 && t_ind != 1)
      return MLIB_FAILURE;

    if (mlib_ImageGetLutType(colormap) == MLIB_SHORT)
      t_ind += 2;
    t_ind = 2 * t_ind;

    if (mlib_ImageGetLutChannels(colormap) == 4)
      t_ind++;
  }

  if (type == MLIB_BIT) {
    mlib_s32 s_bitoff = mlib_ImageGetBitOffset(src);
    mlib_s32 d_bitoff = mlib_ImageGetBitOffset(dst);

    if (nchan != 1 || filter != MLIB_NEAREST)
      return MLIB_FAILURE;
    mlib_ImageAffine_bit_1ch_nn(param, s_bitoff, d_bitoff);
  }
  else {
    switch (filter) {
      case MLIB_NEAREST:

        if (t_ind >= 3)
          t_ind -= 2;                                      /* correct types USHORT, FLOAT, DOUBLE; new values: 1, 2, 3 */

        /* two channels as one channel of next type */
        align = (mlib_addr) (param->dstData) | (mlib_addr) lineAddr[0];
        align |= param->dstYStride | param->srcYStride;
        while (((nchan | (align >> t_ind)) & 1) == 0 && t_ind < MAX_T_IND) {
          nchan >>= 1;
          t_ind++;
        }

        res = mlib_AffineFunArr_nn[4 * t_ind + (nchan - 1)] (param);
        break;

      case MLIB_BILINEAR:

        if (colormap != NULL) {
          res = mlib_AffineFunArr_bl_i[t_ind] (param, colormap);
        }
        else {
          res = mlib_AffineFunArr_bl[4 * t_ind + (nchan - 1)] (param);
        }

        break;

      case MLIB_BICUBIC:
      case MLIB_BICUBIC2:

        if (colormap != NULL) {
          res = mlib_AffineFunArr_bc_i[t_ind] (param, colormap);
        }
        else {
          res = mlib_AffineFunArr_bc[4 * t_ind + (nchan - 1)] (param);
        }

        break;
    }

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

  if (edge == MLIB_EDGE_SRC_PADDED)
    edge = MLIB_EDGE_DST_NO_WRITE;

  if (filter != MLIB_NEAREST && edge != MLIB_EDGE_DST_NO_WRITE) {
    mlib_affine_param param_e[1];
    mlib_d64 buff_lcl1[BUFF_SIZE / 8];

    STORE_PARAM(param_e, lineAddr);
    STORE_PARAM(param_e, filter);

    res = mlib_AffineEdges(param_e, dst, src, buff_lcl1, BUFF_SIZE,
                           kw, kw, kw1, kw1, -1, mtx, MLIB_SHIFT, MLIB_SHIFT);

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

    switch (edge) {
      case MLIB_EDGE_DST_FILL_ZERO:
        mlib_ImageAffineEdgeZero(param, param_e, colormap);
        break;

      case MLIB_EDGE_OP_NEAREST:
        mlib_ImageAffineEdgeNearest(param, param_e);
        break;

      case MLIB_EDGE_SRC_EXTEND:

        if (filter == MLIB_BILINEAR) {
          res = mlib_ImageAffineEdgeExtend_BL(param, param_e, colormap);
        }
        else {
          res = mlib_ImageAffineEdgeExtend_BC(param, param_e, colormap);
        }

        break;
    }

    if (param_e->buff_malloc != NULL)
      mlib_free(param_e->buff_malloc);
  }

  if (param->buff_malloc != NULL)
    mlib_free(param->buff_malloc);

  return res;
}
mlib_status
__mlib_ImageZoomTranslate(
    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)
{
	mlib_type type;
	mlib_s32 nchan;
	mlib_clipping nearest, current;
	mlib_work_image border, *param = &border;

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

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

	type = mlib_ImageGetType(src);
	nchan = mlib_ImageGetChannels(src);

	if (type == MLIB_BIT) {
		if (nchan != 1 || filter != MLIB_NEAREST)
			return (MLIB_FAILURE);
		if (current.width > 0) {
			int s_bitoff = mlib_ImageGetBitOffset(src);
			int d_bitoff = mlib_ImageGetBitOffset(dst);

			return mlib_ImageZoom_BIT_1_Nearest(&border, s_bitoff,
			    d_bitoff);
		}
		return (MLIB_SUCCESS);
	}

	if (filter == MLIB_BICUBIC) {
		if (type == MLIB_BYTE) {
			border.filter1 = (void *)mlib_filters_u8_bc;
			border.filter3 = (void *)mlib_filters_u8_bc_3;
			border.filter4 = (void *)mlib_filters_u8_bc_4;
		} else {
			border.filter1 = (void *)mlib_filters_s16_bc;
			border.filter3 = (void *)mlib_filters_s16_bc_3;
			border.filter4 = (void *)mlib_filters_s16_bc_4;
		}
	} else {
		if (type == MLIB_BYTE) {
			border.filter1 = (void *)mlib_filters_u8_bc2;
			border.filter3 = (void *)mlib_filters_u8_bc2_3;
			border.filter4 = (void *)mlib_filters_u8_bc2_4;
		} else {
			border.filter1 = (void *)mlib_filters_s16_bc2;
			border.filter3 = (void *)mlib_filters_s16_bc2_3;
			border.filter4 = (void *)mlib_filters_s16_bc2_4;
		}
	}

	if (current.width > 0) {
		if (filter == MLIB_NEAREST) {
			RETURN(mlib_zoom_nn_funs[border.ind_fun_nn]);
		} else

		switch (type) {

/* handle MLIB_BYTE data type of image */
		case MLIB_BYTE: {

		    switch (mlib_ImageGetChannels(src)) {

		    case 1:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U8_1s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_1_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U8_1_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_1_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 2:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U8_2s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_2_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U8_2_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_2_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 3:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U8_3s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_3_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U8_3_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_3_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 4:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U8_4s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_4_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U8_4_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_4_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    default:
			    return (MLIB_FAILURE);

		    }
		}
		break;

/* handle MLIB_SHORT data type of image */
		case MLIB_SHORT: {

		    switch (mlib_ImageGetChannels(src)) {

		    case 1:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    RETURN(mlib_m_ImageZoom_S16_1_Bilinear);
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_S16_1_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_1_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 2:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_S16_2s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_2_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_S16_2_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_2_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 3:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_S16_3s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_3_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_S16_3_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_3_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 4:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_S16_4s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_4_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_S16_4_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_4_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    default:
			    return (MLIB_FAILURE);

		    }
		}
		break;

/* handle MLIB_USHORT data type of image */
		case MLIB_USHORT: {

		    switch (mlib_ImageGetChannels(src)) {

		    case 1:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    RETURN(mlib_m_ImageZoom_U16_1_Bilinear);
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U16_1_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_1_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 2:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U16_2s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_2_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U16_2_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_2_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 3:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U16_3s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_3_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U16_3_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_3_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 4:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U16_4s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_4_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U16_4_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_4_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    default:
			    return (MLIB_FAILURE);

		    }
		}
		break;

/* handle MLIB_INT data type of image */
		case MLIB_INT: {

		    switch (mlib_ImageGetChannels(src)) {

		    case 1:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    RETURN(mlib_ImageZoomBilinear_S32_1);
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    RETURN(mlib_ImageZoomBicubic_S32_1);
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 2:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy < 2) {
					    RETURN(
						mlib_ImageZoomBilinear_S32_2s);
				    } else {
					    RETURN(
						mlib_ImageZoomBilinear_S32_2);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    RETURN(mlib_ImageZoomBicubic_S32_2);
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 3:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy < 2 || mlib_ImageGetHeight(dst)
					> 256) {
					    RETURN(
						mlib_ImageZoomBilinear_S32_3s);
				    } else {
					    RETURN(
						mlib_ImageZoomBilinear_S32_3);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    RETURN(mlib_ImageZoomBicubic_S32_3);
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 4:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy < 2 || mlib_ImageGetHeight(dst)
					> 256) {
					    RETURN(
						mlib_ImageZoomBilinear_S32_4s);
				    } else {
					    RETURN(
						mlib_ImageZoomBilinear_S32_4);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    RETURN(mlib_ImageZoomBicubic_S32_4);
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    default:
			    return (MLIB_FAILURE);

		    }
		}
		break;

/* discard any other data types */
		default:
			return (MLIB_FAILURE);
		}
	}

	if (filter == MLIB_NEAREST && edge != MLIB_EDGE_SRC_EXTEND_INDEF) {
		return (MLIB_SUCCESS);
	}

	MLIB_EDGE_RULES
	return (MLIB_SUCCESS);
}
示例#22
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
__mlib_ImageChannelInsert(
    mlib_image *dst,
    const mlib_image *src,
    mlib_s32 cmask)
{
	const mlib_s32 X16 = 0xF;
	const mlib_s32 X8 = 0x7;
	const mlib_s32 X4 = 0x3;
	const mlib_s32 D1 = MLIB_IMAGE_ONEDVECTOR;
	const mlib_s32 A8D1 = MLIB_IMAGE_ALIGNED8 | MLIB_IMAGE_ONEDVECTOR;
	const mlib_s32 A8D2X8 =
	    MLIB_IMAGE_ALIGNED8 | MLIB_IMAGE_STRIDE8X | MLIB_IMAGE_WIDTH8X;
	const mlib_s32 A8D2X4 =
	    MLIB_IMAGE_ALIGNED8 | MLIB_IMAGE_STRIDE8X | MLIB_IMAGE_WIDTH4X;
/* pointer for pixel in src */
	void *sp;

/* pointer for pixel in dst */
	void *dp;

/* normalized channel mask */
	mlib_s32 ncmask = 0;

/* number of channels for src */
	mlib_s32 channels;

/* number of channels for dst */
	mlib_s32 channeld;

/* for src and dst */
	mlib_s32 width, height;

/* strides in bytes for src */
	mlib_s32 strides;

/* strides in bytes for dst */
	mlib_s32 strided;
	mlib_s32 flags;
	mlib_s32 flagd;
	mlib_s32 dsize;
	mlib_s32 i, bit1count = 0;

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

	channels = mlib_ImageGetChannels(src);
	channeld = mlib_ImageGetChannels(dst);
	width = mlib_ImageGetWidth(src);
	height = mlib_ImageGetHeight(src);
	strides = mlib_ImageGetStride(src);
	strided = mlib_ImageGetStride(dst);
	sp = mlib_ImageGetData(src);
	dp = mlib_ImageGetData(dst);
	flags = mlib_ImageGetFlags(src);
	flagd = mlib_ImageGetFlags(dst);
	dsize = width * height;

/* normalize the cmask, and count the number of bit with value 1 */
	for (i = (channeld - 1); i >= 0; i--) {
		if (((cmask & (1 << i)) != 0) && (bit1count < channels)) {
			ncmask += (1 << i);
			bit1count++;
		}
	}

/*
 * do not support the cases in which the number of selected channels is
 * less than the number of channels in the source image
 */

	if (bit1count < channels) {
		return (MLIB_FAILURE);
	}

	if (((channels == 1) && (channeld == 1)) || ((channels == 2) &&
	    (channeld == 2)) || ((channels == 3) && (channeld == 3)) ||
	    ((channels == 4) && (channeld == 4))) {
		return (__mlib_ImageCopy(dst, src));
	}

	switch (mlib_ImageGetType(src)) {
	case MLIB_BYTE:

		if (channels == 1) {
			switch (channeld) {
			case 2:

				if (((flags & D1) == 0) &&
				    ((flagd & D1) == 0) &&
				    ((((mlib_addr)sp) & X16) == 0) &&
				    ((((mlib_addr)dp) & X16) == 0)) {
					mlib_s_ImageChannelInsert_U8_12_A8D1X8(
					    (mlib_u8 *)sp, (mlib_u8 *)dp, dsize,
					    ncmask);
				} else if (((((mlib_addr)sp) & X16) == 0) &&
				    ((((mlib_addr)dp) & X16) == 0) &&
				    ((strides & X16) == 0) &&
				    ((strided & X16) == 0)) {
					mlib_s_ImageChannelInsert_U8_12_A8D2X8(
					    (mlib_u8 *)sp, strides,
					    (mlib_u8 *)dp, strided, width,
					    height, ncmask);
				} else if (((flags & D1) == 0) &&
				    ((flagd & D1) == 0)) {
					mlib_s_ImageChannelInsert_U8_12_D1(
					    (mlib_u8 *)sp, (mlib_u8 *)dp, dsize,
					    ncmask);
				} else {
					mlib_s_ImageChannelInsert_U8_12((mlib_u8
					    *)sp, strides, (mlib_u8 *)dp,
					    strided, width, height, ncmask);
				}
				break;

			case 3:
				mlib_s_ImageChannelInsert_U8((mlib_u8 *)sp,
				    strides, (mlib_u8 *)dp, strided, channels,
				    channeld, width, height, ncmask);
				break;

			case 4:

				if (((flags & D1) == 0) &&
				    ((flagd & D1) == 0) &&
				    ((((mlib_addr)sp) & X16) == 0) &&
				    ((((mlib_addr)dp) & X16) == 0)) {
					mlib_s_ImageChannelInsert_U8_14_A8D1X8(
					    (mlib_u8 *)sp, (mlib_u8 *)dp, dsize,
					    ncmask);
				} else if (((((mlib_addr)sp) & X16) == 0) &&
				    ((((mlib_addr)dp) & X16) == 0) &&
				    ((strides & X16) == 0) &&
				    ((strided & X16) == 0)) {
					mlib_s_ImageChannelInsert_U8_14_A8D2X8(
					    (mlib_u8 *)sp, strides,
					    (mlib_u8 *)dp, strided, width,
					    height, ncmask);
				} else if (((flags & D1) == 0) &&
				    ((flagd & D1) == 0)) {
					mlib_s_ImageChannelInsert_U8_14_D1(
					    (mlib_u8 *)sp, (mlib_u8 *)dp, dsize,
					    ncmask);
				} else {
					mlib_s_ImageChannelInsert_U8_14((mlib_u8
					    *)sp, strides, (mlib_u8 *)dp,
					    strided, width, height, ncmask);
				}

				break;

			default:
				return (MLIB_FAILURE);
			}
		} else {

				mlib_s_ImageChannelInsert_U8((mlib_u8 *)sp,
				    strides, (mlib_u8 *)dp, strided, channels,
				    channeld, width, height, ncmask);
		}

		break;

	case MLIB_SHORT:
	case MLIB_USHORT:

		if (channels == 1) {
			switch (channeld) {
			case 2:

				if (((flags & D1) == 0) &&
				    ((flagd & D1) == 0) &&
				    ((((mlib_addr)sp) & X16) == 0) &&
				    ((((mlib_addr)dp) & X16) == 0)) {
					mlib_s_ImageChannelInsert_S16_12_A8D1X4(
					    (mlib_s16 *)sp, (mlib_s16 *)dp,
					    dsize, ncmask);
				} else if (((((mlib_addr)sp) & X16) == 0) &&
				    ((((mlib_addr)dp) & X16) == 0) &&
				    ((strides & X16) == 0) &&
				    ((strided & X16) == 0)) {
					mlib_s_ImageChannelInsert_S16_12_A8D2X4(
					    (mlib_s16 *)sp, strides,
					    (mlib_s16 *)dp, strided, width,
					    height, ncmask);
				} else if (((flags & D1) == 0) &&
				    ((flagd & D1) == 0)) {
					mlib_s_ImageChannelInsert_S16_12_D1(
					    (mlib_s16 *)sp, (mlib_s16 *)dp,
					    dsize, ncmask);
				} else {
					mlib_s_ImageChannelInsert_S16_12(
					    (mlib_s16 *)sp, strides,
					    (mlib_s16 *)dp, strided, width,
					    height, ncmask);
				}

				break;

			case 3:
				mlib_s_ImageChannelInsert_S16((mlib_s16 *)sp,
				    strides, (mlib_s16 *)dp, strided, channels,
				    channeld, width, height, ncmask);

				break;

			case 4:
				mlib_s_ImageChannelInsert_S16((mlib_s16 *)sp,
				    strides, (mlib_s16 *)dp, strided, channels,
				    channeld, width, height, ncmask);

				break;
			default:
				return (MLIB_FAILURE);
			}
		} else {
			mlib_s_ImageChannelInsert_S16((mlib_s16 *)sp, strides,
			    (mlib_s16 *)dp, strided, channels, channeld, width,
			    height, ncmask);
		}

		break;

	case MLIB_INT:
		mlib_s_ImageChannelInsert_S32((mlib_s32 *)sp, strides,
		    (mlib_s32 *)dp, strided, channels, channeld, width, height,
		    ncmask);
		break;

	case MLIB_FLOAT:
		mlib_s_ImageChannelInsert_S32((mlib_s32 *)sp, strides,
		    (mlib_s32 *)dp, strided, channels, channeld, width, height,
		    ncmask);
		break;

	case MLIB_DOUBLE:
		mlib_s_ImageChannelInsert_D64((mlib_d64 *)sp, strides,
		    (mlib_d64 *)dp, strided, channels, channeld, width, height,
		    ncmask);
		break;

	case MLIB_BIT:
	default:
/* MLIB_BIT is not supported here */
		return (MLIB_FAILURE);
	}

	return (MLIB_SUCCESS);
}
示例#24
0
mlib_status
__mlib_ImageNot(
    mlib_image *dst,
    const mlib_image *src)
{
/* start point in source */
	mlib_u8 *sa;

/* start points in destination */
	mlib_u8 *da;

/* width in bytes of src and dst */
	mlib_s32 width;

/* height in lines of src and dst */
	mlib_s32 height;

/* stride in bytes in src */
	mlib_s32 stride;

/* stride in bytes in dst */
	mlib_s32 dstride;

/* indices for x, y */
	mlib_s32 j;
	mlib_s32 size;
	mlib_s32 type;

	MLIB_IMAGE_CHECK(src);
	MLIB_IMAGE_CHECK(dst);

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

	width = mlib_ImageGetWidth(dst) * mlib_ImageGetChannels(dst);
	height = mlib_ImageGetHeight(dst);
	sa = (mlib_u8 *)mlib_ImageGetData(src);
	da = (mlib_u8 *)mlib_ImageGetData(dst);
	type = mlib_ImageGetType(dst);

	if ((type != MLIB_BYTE) && (type != MLIB_SHORT) &&
	    (type != MLIB_USHORT) && (type != MLIB_BIT) &&
	    (type != MLIB_INT))
		return (MLIB_FAILURE);

	if (type != MLIB_BIT) {

		switch (type) {
		case MLIB_BYTE:
			break;
		case MLIB_SHORT:
		case MLIB_USHORT:
			width *= 2;
			break;
		case MLIB_INT:
			width *= 4;
			break;
		default:
			return (MLIB_FAILURE);
		}

		size = height * width;

		if (!mlib_ImageIsNotOneDvector(src) &&
		    !mlib_ImageIsNotOneDvector(dst) &&
		    ((((mlib_addr)sa ^ (mlib_addr)da) & 7) == 0) &&
		    (size > CASHSIZE)) {
			mlib_s32 tail = 0x40 - ((mlib_addr)da & 0x3F);

			mlib_v_ImageNot_na(sa, da, tail & 0x3F);
			sa += tail & 0x3F;
			da += tail & 0x3F;
			size -= tail & 0x3F;
/* (size >> 6) should be > 1 */
			mlib_v_ImageNot_blk(sa, da, size >> 6);
			sa += size & ~0x3F;
			da += size & ~0x3F;
			mlib_v_ImageNot_na(sa, da, size & 0x3F);
			return (MLIB_SUCCESS);
		} else {
示例#25
0
mlib_status
mlib_ImageGridWarp_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,
    mlib_filter filter,
    mlib_edge edge)
{
	mlib_affine_param param[1];
	mlib_status res = MLIB_SUCCESS;
	mlib_type type;
	mlib_s32 nchan;
	mlib_s32 srcWidth, dstWidth, srcHeight, dstHeight;
	mlib_s32 srcYStride, dstYStride;
	mlib_s32 *warp_tbl, sArr[5 + 2 * BUFF_SIZE], t_ind = 0;
	mlib_s32 *leftEdges, *rightEdges, *xStarts, *yStarts;
	mlib_s32 leArr[BUFF_SIZE], reArr[BUFF_SIZE], xsArr[BUFF_SIZE],
	    ysArr[BUFF_SIZE];
	mlib_u8 *laArr[BUFF_SIZE + 4], **lineAddr, *memBuffer = NULL;
	mlib_u8 *srcLinePtr;
	mlib_u8 *srcData, *dstData_beg, *dstData;
	mlib_u8 *paddings;
	mlib_s32 align;
	mlib_s32 xFirst, xLast, xSkip, xRest;
	mlib_s32 yFirst, yLast, ySkip, yRest;
	mlib_d64 minX, minY, maxX, maxY;
	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, offset;
	mlib_s32 shift_left, shift_right, max_xsize;
	mlib_s32 i;

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

	if (xNumCells == 0 || yNumCells == 0)
		return (MLIB_SUCCESS);

	if (xWarpPos == NULL || yWarpPos == NULL)
		return (MLIB_FAILURE);

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

	if (xNumCells < 0 || yNumCells <= 0 || xStep <= 0 || yStep <= 0)
		return (MLIB_FAILURE);

	srcData = mlib_ImageGetData(src);
	dstData_beg = mlib_ImageGetData(dst);
	type = mlib_ImageGetType(dst);
	nchan = mlib_ImageGetChannels(dst);
	srcWidth = mlib_ImageGetWidth(src);
	srcHeight = mlib_ImageGetHeight(src);
	dstWidth = mlib_ImageGetWidth(dst);
	dstHeight = mlib_ImageGetHeight(dst);
	srcYStride = mlib_ImageGetStride(src);
	dstYStride = mlib_ImageGetStride(dst);
	paddings = mlib_ImageGetPaddings(src);

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

	if (xStart >= dstWidth ||
	    ((xStart + xStep * xNumCells) <= 0) ||
	    yStart >= dstHeight || ((yStart + yStep * yNumCells) <= 0))
		return (MLIB_SUCCESS);

	if (srcHeight < BUFF_SIZE && dstHeight < BUFF_SIZE) {
		lineAddr = laArr;
		leftEdges = leArr;
		rightEdges = reArr;
		xStarts = xsArr;
		yStarts = ysArr;
		warp_tbl = sArr;
	} else {
		memBuffer =
		    __mlib_malloc((6 * dstHeight + 8) * sizeof (mlib_s32) +
		    (srcHeight + 4) * sizeof (mlib_u8 *));

		if (memBuffer == NULL)
			return (MLIB_FAILURE);
		leftEdges = (mlib_s32 *)(memBuffer);
		rightEdges =
		    (mlib_s32 *)(memBuffer + dstHeight * sizeof (mlib_s32));
		xStarts =
		    (mlib_s32 *)(memBuffer + 2 * dstHeight * sizeof (mlib_s32));
		yStarts =
		    (mlib_s32 *)(memBuffer + 3 * dstHeight * sizeof (mlib_s32));
		warp_tbl =
		    (mlib_s32 *)(memBuffer + 4 * dstHeight * sizeof (mlib_s32));
		lineAddr =
		    (mlib_u8 **)(memBuffer + (6 * dstHeight +
		    8) * sizeof (mlib_s32));
	}

	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;

	srcLinePtr = (mlib_u8 *)srcData;
	lineAddr += 2;
	for (i = -2; i < srcHeight + 2; i++) {
		lineAddr[i] = srcLinePtr + i * srcYStride;
	}

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

	if (filter == MLIB_NEAREST) {
		if (t_ind >= 3)
/* correct types USHORT, FLOAT, DOUBLE; new values: 1, 2, 3 */
			t_ind -= 2;

/* two channels as one channel of next type */
		align =
		    (mlib_s32)dstData_beg | (mlib_s32)srcData | dstYStride |
		    srcYStride;
#ifndef i386	/* do not perform the copying by mlib_d64 data type for x86 */
		while (((nchan | (align >> t_ind)) & 1) == 0 && t_ind < 3)
#else /* i386 ( do not perform the copying by mlib_d64 data type for x86 ) */
		while (((nchan | (align >> t_ind)) & 1) == 0 && t_ind < 2)
#endif /* i386 ( do not perform the copying by mlib_d64 data type for x86 ) */
		{
			nchan >>= 1;
			t_ind++;
		}
	}

	switch (filter) {
	case MLIB_NEAREST:
		minX = 0;
		minY = 0;
		maxX = srcWidth;
		maxY = srcHeight;
		offset = 0;
		break;

	case MLIB_BILINEAR:
		minX = 0.5;
		minY = 0.5;
		maxX = srcWidth - 0.5;
		maxY = srcHeight - 0.5;
		offset = 0.5;
		break;

	case MLIB_BICUBIC:
	case MLIB_BICUBIC2:
		minX = 1.5;
		minY = 1.5;
		maxX = srcWidth - 1.5;
		maxY = srcHeight - 1.5;
		offset = 0.5;
		break;

	default:

		if (memBuffer != NULL) {
			__mlib_free(memBuffer);
		}

		return (MLIB_FAILURE);
	}

	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 (memBuffer != NULL) {
			__mlib_free(memBuffer);
		}

		return (MLIB_SUCCESS);
	}

/*
 *   STORE_PARAM(param, src);
 */
	param->src = (void *)src;

	STORE_PARAM(param, dst);
	STORE_PARAM(param, lineAddr);
	STORE_PARAM(param, leftEdges);
	STORE_PARAM(param, rightEdges);
	STORE_PARAM(param, xStarts);
	STORE_PARAM(param, yStarts);
	STORE_PARAM(param, srcYStride);
	STORE_PARAM(param, dstYStride);
	STORE_PARAM(param, warp_tbl);
	STORE_PARAM(param, filter);

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

			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 -
					    offset) * MLIB_PREC);
					yStarts[i] =
					    (mlib_s32)((y0 -
					    offset) * MLIB_PREC);
					warp_tbl[2 * i] =
					    (mlib_s32)(tmp_dx * MLIB_PREC);
					warp_tbl[2 * i + 1] =
					    (mlib_s32)(tmp_dy * MLIB_PREC);
				}
			} 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 -
					    offset) * MLIB_PREC);
					yStarts[i] =
					    (mlib_s32)((tmp_y0 -
					    offset) * MLIB_PREC);
					warp_tbl[2 * i] =
					    (mlib_s32)(tmp_dx * MLIB_PREC);
					warp_tbl[2 * i + 1] =
					    (mlib_s32)(tmp_dy * MLIB_PREC);
				}
			}

			if (max_xsize > 0) {
				mlib_s32 yStart = yBeg;
				mlib_s32 yFinish = yEnd;

				dstData = dstData_beg + (yBeg - 1) * dstYStride;

				STORE_PARAM(param, dstData);
				STORE_PARAM(param, yStart);
				STORE_PARAM(param, yFinish);
				STORE_PARAM(param, max_xsize);

				switch (filter) {
				case MLIB_NEAREST:
					res =
					    mlib_AffineFunArr_nn[4 * t_ind +
					    (nchan - 1)] (param);
					break;
				case MLIB_BILINEAR:
					res =
					    mlib_AffineFunArr_bl[4 * t_ind +
					    (nchan - 1)] (param);
					break;
				case MLIB_BICUBIC:
				case MLIB_BICUBIC2:
					res =
					    mlib_AffineFunArr_bc[4 * t_ind +
					    (nchan - 1)] (param);
					break;
				}

				if (res != MLIB_SUCCESS) {
					if (memBuffer != NULL)
						__mlib_free(memBuffer);
					return (res);
				}
			}
		}
	}

	if (memBuffer != NULL) {
		__mlib_free(memBuffer);
	}

	return (MLIB_SUCCESS);
}