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 = ¤t; 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_ImageConv5x5Index( mlib_image *dst, const mlib_image *src, const mlib_s32 *kernel, mlib_s32 scale, mlib_edge edge, const void *colormap) { mlib_status stat; mlib_type src_dtype, lut_type; mlib_s32 zero[4]; mlib_s32 offset; if (dst == NULL || src == NULL || colormap == NULL || kernel == NULL) return (MLIB_FAILURE); MLIB_IMAGE_FULL_EQUAL(dst, src); MLIB_IMAGE_HAVE_CHAN(src, 1); src_dtype = mlib_ImageGetType(src); lut_type = mlib_ImageGetLutType(colormap); offset = (mlib_s32)mlib_ImageGetLutOffset(colormap); zero[0] = zero[1] = zero[2] = zero[3] = offset; if (mlib_ImageGetWidth(src) < 5 || mlib_ImageGetHeight(src) < 5) return (MLIB_FAILURE); if (((lut_type == MLIB_BYTE) && (scale < 16 || scale > 31)) || ((lut_type == MLIB_SHORT) && (scale < 17 || scale > 32))) return (MLIB_FAILURE); switch (src_dtype) { case MLIB_BYTE: switch (lut_type) { case MLIB_BYTE: switch (edge) { case MLIB_EDGE_DST_FILL_ZERO: stat = mlib_v_conv5x5Index_8_8nw(src, dst, kernel, scale, colormap); if (stat != MLIB_SUCCESS) break; stat = mlib_ImageConvClearEdge(dst, 2, 2, 2, 2, zero, 1); break; case MLIB_EDGE_DST_COPY_SRC: stat = mlib_v_conv5x5Index_8_8nw(src, dst, kernel, scale, colormap); if (stat != MLIB_SUCCESS) break; stat = mlib_ImageConvCopyEdge(dst, src, 2, 2, 2, 2, 1); break; case MLIB_EDGE_SRC_EXTEND: stat = mlib_v_conv5x5Index_8_8ext(src, dst, kernel, scale, colormap); break; case MLIB_EDGE_DST_NO_WRITE: default: stat = mlib_v_conv5x5Index_8_8nw(src, dst, kernel, scale, colormap); break; } break; case MLIB_SHORT: switch (edge) { case MLIB_EDGE_DST_FILL_ZERO: stat = mlib_conv5x5Index_16_8nw(src, dst, kernel, scale, colormap); if (stat != MLIB_SUCCESS) break; stat = mlib_ImageConvClearEdge(dst, 2, 2, 2, 2, zero, 1); break; case MLIB_EDGE_DST_COPY_SRC: stat = mlib_conv5x5Index_16_8nw(src, dst, kernel, scale, colormap); if (stat != MLIB_SUCCESS) break; stat = mlib_ImageConvCopyEdge(dst, src, 2, 2, 2, 2, 1); break; case MLIB_EDGE_SRC_EXTEND: stat = mlib_conv5x5Index_16_8ext(src, dst, kernel, scale, colormap); break; case MLIB_EDGE_DST_NO_WRITE: default: stat = mlib_conv5x5Index_16_8nw(src, dst, kernel, scale, colormap); break; } break; } break; case MLIB_SHORT: /* convert wid from pixels to bytes */ switch (lut_type) { case MLIB_SHORT: switch (edge) { case MLIB_EDGE_DST_FILL_ZERO: stat = mlib_conv5x5Index_16_16nw(src, dst, kernel, scale, colormap); if (stat != MLIB_SUCCESS) break; stat = mlib_ImageConvClearEdge(dst, 2, 2, 2, 2, zero, 1); break; case MLIB_EDGE_DST_COPY_SRC: stat = mlib_conv5x5Index_16_16nw(src, dst, kernel, scale, colormap); if (stat != MLIB_SUCCESS) break; stat = mlib_ImageConvCopyEdge(dst, src, 2, 2, 2, 2, 1); break; case MLIB_EDGE_SRC_EXTEND: stat = mlib_conv5x5Index_16_16ext(src, dst, kernel, scale, colormap); break; case MLIB_EDGE_DST_NO_WRITE: default: stat = mlib_conv5x5Index_16_16nw(src, dst, kernel, scale, colormap); break; } break; case MLIB_BYTE: switch (edge) { case MLIB_EDGE_DST_FILL_ZERO: stat = mlib_v_conv5x5Index_8_16nw(src, dst, kernel, scale, colormap); if (stat != MLIB_SUCCESS) break; stat = mlib_ImageConvClearEdge(dst, 2, 2, 2, 2, zero, 1); break; case MLIB_EDGE_DST_COPY_SRC: stat = mlib_v_conv5x5Index_8_16nw(src, dst, kernel, scale, colormap); if (stat != MLIB_SUCCESS) break; stat = mlib_ImageConvCopyEdge(dst, src, 2, 2, 2, 2, 1); break; case MLIB_EDGE_SRC_EXTEND: stat = mlib_v_conv5x5Index_8_16ext(src, dst, kernel, scale, colormap); break; case MLIB_EDGE_DST_NO_WRITE: default: stat = mlib_v_conv5x5Index_8_16nw(src, dst, kernel, scale, colormap); break; } break; } break; default: stat = MLIB_FAILURE; break; } return (stat); }
void mlib_ImageZoomIndexExtend_U8_Bicubic2( mlib_work_image * param) { VARIABLE_EDGE(mlib_u8); VARIABLE_SRC_EXTEND(mlib_u8); VARIABLE_SRC_EXTEND_BC; void *colormap = GetElemStruct(colormap); mlib_type colortype = mlib_ImageGetLutType(colormap); mlib_pack_func pack_func; mlib_u8 *tdpbuf = GetElemStruct(buffer_dp); channels = mlib_ImageGetLutChannels(colormap); if (colortype == MLIB_BYTE) { mlib_u8 *csp, *dpbuf = GetElemStruct(buffer_dp); mlib_f32 *ctable = (mlib_f32 *)mlib_ImageGetLutNormalTable(colormap) - mlib_ImageGetLutOffset(colormap); if (channels == 3) pack_func = (mlib_pack_func) & mlib_ImageColorTrue2IndexLine_U8_U8_3; else pack_func = (mlib_pack_func) & mlib_ImageColorTrue2IndexLine_U8_U8_4; /* *********************************************************** */ #if defined(MLIB_XY_SHIFT) #undef MLIB_XY_SHIFT #define MLIB_XY_SHIFT 4 #endif /* defined(MLIB_XY_SHIFT) */ /* *********************************************************** */ #if defined(MLIB_XY_MASK) #undef MLIB_XY_MASK #define MLIB_XY_MASK (((1 << 8) - 1) << 4) #endif /* defined(MLIB_XY_MASK) */ MLIB_SRC_EXTEND_INDEX_BC(mlib_u8, dp0, x, y, w, h, r, c, x0, y0, w1, h1, mlib_filters_u8f_bc2, RES_U8_INDEX, HOR); MLIB_SRC_EXTEND_INDEX_BC(mlib_u8, dp3, x, y, w, h, r, c, x0, y2, w1, h3, mlib_filters_u8f_bc2, RES_U8_INDEX, HOR); MLIB_SRC_EXTEND_INDEX_BC(mlib_u8, dp1, y, x, h, w, c, r, y1, x0, h2, w2, mlib_filters_u8f_bc2, RES_U8_INDEX, VER); MLIB_SRC_EXTEND_INDEX_BC(mlib_u8, dp2, y, x, h, w, c, r, y1, x1, h2, w3, mlib_filters_u8f_bc2, RES_U8_INDEX, VER); } else { mlib_s16 *csp, *dpbuf = GetElemStruct(buffer_dp); mlib_d64 *ctable = (mlib_d64 *)mlib_ImageGetLutNormalTable(colormap) - mlib_ImageGetLutOffset(colormap); if (channels == 3) pack_func = (mlib_pack_func) & mlib_ImageColorTrue2IndexLine_S16_U8_3; else pack_func = (mlib_pack_func) & mlib_ImageColorTrue2IndexLine_S16_U8_4; /* *********************************************************** */ #if defined(MLIB_XY_SHIFT) #undef MLIB_XY_SHIFT #define MLIB_XY_SHIFT 3 #endif /* defined(MLIB_XY_SHIFT) */ /* *********************************************************** */ #if defined(MLIB_XY_MASK) #undef MLIB_XY_MASK #define MLIB_XY_MASK (((1 << 9) - 1) << 4) #endif /* defined(MLIB_XY_MASK) */ MLIB_SRC_EXTEND_INDEX_BC(mlib_s16, dp0, x, y, w, h, r, c, x0, y0, w1, h1, mlib_filters_s16f_bc2, RES_S16_INDEX, HOR); MLIB_SRC_EXTEND_INDEX_BC(mlib_s16, dp3, x, y, w, h, r, c, x0, y2, w1, h3, mlib_filters_s16f_bc2, RES_S16_INDEX, HOR); MLIB_SRC_EXTEND_INDEX_BC(mlib_s16, dp1, y, x, h, w, c, r, y1, x0, h2, w2, mlib_filters_s16f_bc2, RES_S16_INDEX, VER); MLIB_SRC_EXTEND_INDEX_BC(mlib_s16, dp2, y, x, h, w, c, r, y1, x1, h2, w3, mlib_filters_s16f_bc2, RES_S16_INDEX, VER); } }
void mlib_ImageZoomIndexExtend_S16_Bilinear( mlib_work_image * param) { VARIABLE_EDGE(mlib_s16); VARIABLE_SRC_EXTEND(mlib_s16); void *colormap = GetElemStruct(colormap); mlib_type colortype = mlib_ImageGetLutType(colormap); mlib_pack_func pack_func; mlib_s16 *tdpbuf = GetElemStruct(buffer_dp); channels = mlib_ImageGetLutChannels(colormap); if (colortype == MLIB_BYTE) { mlib_u8 *csp, *dpbuf = GetElemStruct(buffer_dp); mlib_f32 *ctable = (mlib_f32 *)mlib_ImageGetLutNormalTable(colormap) - mlib_ImageGetLutOffset(colormap); if (channels == 3) pack_func = (mlib_pack_func) & mlib_ImageColorTrue2IndexLine_U8_S16_3; else pack_func = (mlib_pack_func) & mlib_ImageColorTrue2IndexLine_U8_S16_4; MLIB_SRC_EXTEND_INDEX_BL(mlib_u8, dp0, x, y, w, h, x0, y0, w1, h1, HOR); MLIB_SRC_EXTEND_INDEX_BL(mlib_u8, dp3, x, y, w, h, x0, y2, w1, h3, HOR); MLIB_SRC_EXTEND_INDEX_BL(mlib_u8, dp1, y, x, h, w, y1, x0, h2, w2, VER); MLIB_SRC_EXTEND_INDEX_BL(mlib_u8, dp2, y, x, h, w, y1, x1, h2, w3, VER); } else { mlib_s16 *csp, *dpbuf = GetElemStruct(buffer_dp); mlib_d64 *ctable = (mlib_d64 *)mlib_ImageGetLutNormalTable(colormap) - mlib_ImageGetLutOffset(colormap); if (channels == 3) pack_func = (mlib_pack_func) & mlib_ImageColorTrue2IndexLine_S16_S16_3; else pack_func = (mlib_pack_func) & mlib_ImageColorTrue2IndexLine_S16_S16_4; MLIB_SRC_EXTEND_INDEX_BL(mlib_s16, dp0, x, y, w, h, x0, y0, w1, h1, HOR); MLIB_SRC_EXTEND_INDEX_BL(mlib_s16, dp3, x, y, w, h, x0, y2, w1, h3, HOR); MLIB_SRC_EXTEND_INDEX_BL(mlib_s16, dp1, y, x, h, w, y1, x0, h2, w2, VER); MLIB_SRC_EXTEND_INDEX_BL(mlib_s16, dp2, y, x, h, w, y1, x1, h2, w3, VER); } }
mlib_status mlib_ImageAffineEdgeExtend_BL(mlib_affine_param *param, mlib_affine_param *param_e, const void *colormap) { GET_EDGE_PARAMS(); mlib_d64 scale = 1.0 / (mlib_d64) MLIB_PREC; mlib_s32 xDelta, yDelta, xFlag, yFlag; mlib_d64 t, u, pix0; mlib_d64 a00, a01, a10, a11; if (colormap != NULL) { mlib_s32 max_xsize = param_e->max_xsize; mlib_type ltype = mlib_ImageGetLutType(colormap); mlib_d64 *plut = (mlib_d64 *) mlib_ImageGetLutDoubleData(colormap); void *buff; channels = mlib_ImageGetLutChannels(colormap); plut -= channels * mlib_ImageGetLutOffset(colormap); if (max_xsize == 0) { return MLIB_SUCCESS; } if (ltype == MLIB_BYTE) { buff = mlib_malloc(channels * max_xsize); } else { buff = mlib_malloc(channels * max_xsize * sizeof(mlib_s16)); } if (buff == NULL) return MLIB_FAILURE; switch (ltype) { case MLIB_BYTE: switch (type) { case MLIB_BYTE: MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_u8i, mlib_u8); break; case MLIB_SHORT: srcStride >>= 1; MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_u8i, mlib_s16); break; } break; case MLIB_SHORT: switch (type) { case MLIB_BYTE: MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_s16i, mlib_u8); break; case MLIB_SHORT: srcStride >>= 1; MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_s16i, mlib_s16); break; } break; } mlib_free(buff); return MLIB_SUCCESS; }
mlib_status 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_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); }