mlib_image *mlib_ImageSetSubimage(mlib_image *dst, const mlib_image *src, mlib_s32 x, mlib_s32 y, mlib_s32 w, mlib_s32 h) { mlib_type type = src -> type; mlib_s32 channels = src -> channels; mlib_s32 stride = src -> stride; mlib_u8 *data = src -> data; mlib_s32 bitoffset; data += y * stride; switch (type) { case MLIB_DOUBLE: data += channels * x * 8; break; case MLIB_FLOAT: case MLIB_INT: data += channels * x * 4; break; case MLIB_USHORT: case MLIB_SHORT: data += channels * x * 2; break; case MLIB_BYTE: data += channels * x; break; case MLIB_BIT: bitoffset = src -> bitoffset + channels * x; data += (bitoffset >= 0) ? bitoffset/8 : (bitoffset - 7)/8; /* with rounding toward -Inf */ bitoffset &= 7; break; default: return NULL; } if (h > 0) { dst = mlib_ImageSet(dst, type, channels, w, h, stride, data); } else { h = - h; dst = mlib_ImageSet(dst, type, channels, w, h, - stride, data + (h - 1)*stride); } if (dst != NULL && type == MLIB_BIT) { dst -> bitoffset = bitoffset; } return dst; }
mlib_image *mlib_ImageCreateStruct(mlib_type type, mlib_s32 channels, mlib_s32 width, mlib_s32 height, mlib_s32 stride, const void *data) { mlib_image *image; if (stride <= 0) { return NULL; } image = (mlib_image *)mlib_malloc(sizeof(mlib_image)); if (image == NULL) { return NULL; } if (mlib_ImageSet(image, type, channels, width, height, stride, data) == NULL) { mlib_free(image); image = NULL; } return image; }
mlib_status __mlib_ImageAutoCorrel( mlib_d64 *correl, const mlib_image *img, mlib_s32 dx, mlib_s32 dy) { mlib_image images[2], *img1, *img2; /* height of image */ mlib_s32 height; /* width of image */ mlib_s32 width; /* type of image */ mlib_type type; /* channels of image */ mlib_s32 channels; /* stride of image */ mlib_s32 stride; /* data pointer of image */ mlib_u8 *data, *data2; mlib_d64 rez[4]; mlib_d64 divider; /* check for obvious errors */ MLIB_IMAGE_CHECK(img); if (correl == NULL) return (MLIB_NULLPOINTER); if (dx < 0 || dy < 0) return (MLIB_OUTOFRANGE); width = mlib_ImageGetWidth(img) - dx; height = mlib_ImageGetHeight(img) - dy; type = mlib_ImageGetType(img); channels = mlib_ImageGetChannels(img); stride = mlib_ImageGetStride(img); data = (mlib_u8 *)mlib_ImageGetData(img); divider = 1.0 / ((mlib_d64)width * height); switch (type) { case MLIB_BYTE: data2 = data + dy * stride + channels * dx; break; case MLIB_USHORT: case MLIB_SHORT: data2 = data + dy * stride + channels * dx * 2; break; case MLIB_INT: data2 = data + dy * stride + channels * dx * 4; break; default: return (MLIB_FAILURE); } img1 = mlib_ImageSet(&images[0], type, channels, width, height, stride, (void *)data); if (!img1) return (MLIB_FAILURE); img2 = mlib_ImageSet(&images[1], type, channels, width, height, stride, (void *)data2); if (!img2) return (MLIB_FAILURE); switch (type) { /* handle MLIB_BYTE data type of image */ case MLIB_BYTE: if (channels == 3) mlib_c_ImageCrossCorrel_U8_3(img1, img2, rez); else mlib_c_ImageCrossCorrel_U8_124(img1, img2, rez); break; /* handle MLIB_USHORT data type of image */ case MLIB_USHORT: if (channels == 3) mlib_c_ImageCrossCorrel_U16_3(img1, img2, rez); else mlib_c_ImageCrossCorrel_U16_124(img1, img2, rez); break; /* handle MLIB_SHORT data type of image */ case MLIB_SHORT: if (channels == 3) mlib_c_ImageCrossCorrel_S16_3(img1, img2, rez); else mlib_c_ImageCrossCorrel_S16_124(img1, img2, rez); break; /* handle MLIB_INT data type of image */ case MLIB_INT: if (channels == 3) mlib_c_ImageCrossCorrel_S32_3(img1, img2, rez); else mlib_c_ImageCrossCorrel_S32_124(img1, img2, rez); break; /* discard any other data types */ default: return (MLIB_FAILURE); } switch (channels) { case 1: correl[0] = (rez[0] + rez[1] + rez[2] + rez[3]) * divider; break; case 2: correl[0] = (rez[0] + rez[2]) * divider; correl[1] = (rez[1] + rez[3]) * divider; break; case 4: correl[3] = rez[3] * divider; case 3: correl[0] = rez[0] * divider; correl[1] = rez[1] * divider; correl[2] = rez[2] * divider; } return (MLIB_SUCCESS); }
/* *********************************************************** */ mlib_status __mlib_ImageExtrema2_Fp( mlib_d64 *min, mlib_d64 *max, const mlib_image *img, mlib_s32 xStart, mlib_s32 yStart, mlib_s32 xPeriod, mlib_s32 yPeriod) { mlib_type type; void *sl; mlib_s32 nchan, xsize, ysize, slb, tsize; mlib_d64 dmin[4], dmax[4]; MLIB_IMAGE_CHECK(img); if (min == NULL || max == NULL) return (MLIB_NULLPOINTER); if (xPeriod < 1 || yPeriod < 1) return (MLIB_OUTOFRANGE); while (xStart < 0) xStart += xPeriod; while (yStart < 0) yStart += yPeriod; MLIB_IMAGE_GET_ALL_PARAMS(img, type, nchan, xsize, ysize, slb, sl); if (type == MLIB_DOUBLE) tsize = 8; else if (type == MLIB_FLOAT) tsize = 4; else return (MLIB_FAILURE); sl = (mlib_u8 *)sl + yStart * slb + xStart * nchan * tsize; xsize = (xsize - xStart); ysize = ((ysize - yStart) + (yPeriod - 1)) / yPeriod; slb = slb * yPeriod; if (xsize <= 0 || ysize <= 0) return (MLIB_SUCCESS); if (type == MLIB_FLOAT && xPeriod == 1) { mlib_image tmp_img; if (mlib_ImageSet(&tmp_img, type, nchan, xsize, ysize, slb, sl) != NULL) { if (__mlib_ImageMinimum_Fp(min, &tmp_img) == MLIB_SUCCESS && __mlib_ImageMaximum_Fp(max, &tmp_img) == MLIB_SUCCESS) return (MLIB_SUCCESS); } } xsize *= nchan; slb /= tsize; if (type == MLIB_DOUBLE) { dmin[0] = min[0] = MLIB_D64_MAX; dmax[0] = max[0] = MLIB_D64_MIN; switch (nchan) { case 1: mlib_ImageExtrema2_4_d64(dmin, dmax, sl, xsize, ysize, slb, xPeriod, 2 * xPeriod, 3 * xPeriod, 4 * xPeriod); MIN(dmin[0], dmin[1]); MAX(dmax[0], dmax[1]); MIN(dmin[0], dmin[2]); MAX(dmax[0], dmax[2]); MIN(dmin[0], dmin[3]); MAX(dmax[0], dmax[3]); min[0] = dmin[0]; max[0] = dmax[0]; break; case 2: mlib_ImageExtrema2_4_d64(dmin, dmax, sl, xsize, ysize, slb, 1, 2 * xPeriod, 2 * xPeriod + 1, 4 * xPeriod); MIN(dmin[0], dmin[2]); MAX(dmax[0], dmax[2]); MIN(dmin[1], dmin[3]); MAX(dmax[1], dmax[3]); min[0] = dmin[0]; max[0] = dmax[0]; min[1] = dmin[1]; max[1] = dmax[1]; break; case 3: mlib_ImageExtrema2_3_d64(min, max, sl, xsize, ysize, slb, 3 * xPeriod); break; case 4: mlib_ImageExtrema2_4_d64(min, max, sl, xsize, ysize, slb, 1, 2, 3, 4 * xPeriod); break; default: return (MLIB_FAILURE); } } else { dmin[0] = min[0] = MLIB_F32_MAX; dmax[0] = max[0] = MLIB_F32_MIN; switch (nchan) { case 1: mlib_ImageExtrema2_2_f32(dmin, dmax, sl, xsize, ysize, slb, xPeriod, 2 * xPeriod); MIN(dmin[0], dmin[1]); MAX(dmax[0], dmax[1]); min[0] = dmin[0]; max[0] = dmax[0]; break; case 2: mlib_ImageExtrema2_2_f32(min, max, sl, xsize, ysize, slb, 1, 2 * xPeriod); break; case 3: mlib_ImageExtrema2_3_f32(min, max, sl, xsize, ysize, slb, 3 * xPeriod); break; case 4: mlib_ImageExtrema2_4_f32(min, max, sl, xsize, ysize, slb, 1, 2, 3, 4 * xPeriod); break; default: return (MLIB_FAILURE); } }; return (MLIB_SUCCESS); }
/* *********************************************************** */ mlib_status __mlib_ImageExtrema2( mlib_s32 *min, mlib_s32 *max, const mlib_image *img, mlib_s32 xStart, mlib_s32 yStart, mlib_s32 xPeriod, mlib_s32 yPeriod) { mlib_type type; void *sl; mlib_s32 nchan, xsize, ysize, slb, tsize; mlib_s32 dmin[4], dmax[4]; MLIB_IMAGE_CHECK(img); if (min == NULL || max == NULL) return (MLIB_NULLPOINTER); if (xPeriod < 1 || yPeriod < 1) return (MLIB_OUTOFRANGE); while (xStart < 0) xStart += xPeriod; while (yStart < 0) yStart += yPeriod; MLIB_IMAGE_GET_ALL_PARAMS(img, type, nchan, xsize, ysize, slb, sl); if (type == MLIB_BYTE) tsize = 1; else if (type == MLIB_SHORT) tsize = 2; else if (type == MLIB_USHORT) tsize = 2; else if (type == MLIB_INT) tsize = 4; else return (MLIB_FAILURE); sl = (mlib_u8 *)sl + yStart * slb + xStart * nchan * tsize; xsize = (xsize - xStart); ysize = ((ysize - yStart) + (yPeriod - 1)) / yPeriod; slb = slb * yPeriod; if (xsize <= 0 || ysize <= 0) return (MLIB_SUCCESS); /* on VIS and (xPeriod == 1) branch to mlib_ImageMinimum/mlib_ImageMaximum */ if (xPeriod == 1) { mlib_image tmp_img; if (mlib_ImageSet(&tmp_img, type, nchan, xsize, ysize, slb, sl) != NULL) { if (mlib_ImageExtrema2_fast(min, max, &tmp_img) == MLIB_SUCCESS) return (MLIB_SUCCESS); } } xsize *= nchan; slb /= tsize; if (type == MLIB_BYTE) { dmin[0] = min[0] = MLIB_U8_MAX; dmax[0] = max[0] = MLIB_U8_MIN; switch (nchan) { case 1: mlib_ImageExtrema2_2_u8(dmin, dmax, sl, xsize, ysize, slb, xPeriod, 2 * xPeriod, 3 * xPeriod, 4 * xPeriod); break; case 2: mlib_ImageExtrema2_2_u8(min, max, sl, xsize, ysize, slb, 1, 2 * xPeriod, 2 * xPeriod + 1, 4 * xPeriod); break; case 3: mlib_ImageExtrema2_3_u8(min, max, sl, xsize, ysize, slb, 3 * xPeriod); break; case 4: mlib_ImageExtrema2_4_u8(min, max, sl, xsize, ysize, slb, 4 * xPeriod); break; default: return (MLIB_FAILURE); } } else if (type == MLIB_SHORT) { dmin[0] = min[0] = MLIB_S16_MAX; dmax[0] = max[0] = MLIB_S16_MIN; switch (nchan) { case 1: mlib_ImageExtrema2_2_s16(dmin, dmax, sl, xsize, ysize, slb, xPeriod, 2 * xPeriod, 3 * xPeriod, 4 * xPeriod); break; case 2: mlib_ImageExtrema2_2_s16(min, max, sl, xsize, ysize, slb, 1, 2 * xPeriod, 2 * xPeriod + 1, 4 * xPeriod); break; case 3: mlib_ImageExtrema2_3_s16(min, max, sl, xsize, ysize, slb, 3 * xPeriod); break; case 4: mlib_ImageExtrema2_4_s16(min, max, sl, xsize, ysize, slb, 4 * xPeriod); break; default: return (MLIB_FAILURE); } } else if (type == MLIB_USHORT) { dmin[0] = min[0] = MLIB_U16_MAX; dmax[0] = max[0] = MLIB_U16_MIN; switch (nchan) { case 1: mlib_ImageExtrema2_2_u16(dmin, dmax, sl, xsize, ysize, slb, xPeriod, 2 * xPeriod, 3 * xPeriod, 4 * xPeriod); break; case 2: mlib_ImageExtrema2_2_u16(min, max, sl, xsize, ysize, slb, 1, 2 * xPeriod, 2 * xPeriod + 1, 4 * xPeriod); break; case 3: mlib_ImageExtrema2_3_u16(min, max, sl, xsize, ysize, slb, 3 * xPeriod); break; case 4: mlib_ImageExtrema2_4_u16(min, max, sl, xsize, ysize, slb, 4 * xPeriod); break; default: return (MLIB_FAILURE); } } else if (type == MLIB_INT) { dmin[0] = min[0] = MLIB_S32_MAX; dmax[0] = max[0] = MLIB_S32_MIN; switch (nchan) { case 1: mlib_ImageExtrema2_124_s32(dmin, dmax, sl, xsize, ysize, slb, xPeriod, 2 * xPeriod, 3 * xPeriod, 4 * xPeriod); MIN(dmin[0], dmin[1]); MAX(dmax[0], dmax[1]); MIN(dmin[0], dmin[2]); MAX(dmax[0], dmax[2]); MIN(dmin[0], dmin[3]); MAX(dmax[0], dmax[3]); min[0] = dmin[0]; max[0] = dmax[0]; return (MLIB_SUCCESS); case 2: mlib_ImageExtrema2_124_s32(dmin, dmax, sl, xsize, ysize, slb, 1, 2 * xPeriod, 2 * xPeriod + 1, 4 * xPeriod); MIN(dmin[0], dmin[2]); MAX(dmax[0], dmax[2]); MIN(dmin[1], dmin[3]); MAX(dmax[1], dmax[3]); min[0] = dmin[0]; max[0] = dmax[0]; min[1] = dmin[1]; max[1] = dmax[1]; return (MLIB_SUCCESS); case 3: mlib_ImageExtrema2_3_s32(min, max, sl, xsize, ysize, slb, 3 * xPeriod); return (MLIB_SUCCESS); case 4: mlib_ImageExtrema2_124_s32(min, max, sl, xsize, ysize, slb, 1, 2, 3, 4 * xPeriod); return (MLIB_SUCCESS); default: return (MLIB_FAILURE); } } if (nchan == 1) { MIN(dmin[0], dmin[1]); MAX(dmax[0], dmax[1]); min[0] = dmin[0]; max[0] = dmax[0]; } return (MLIB_SUCCESS); }