diff options
author | Pixel <pixel@nobis-crew.org> | 2010-06-14 23:47:31 -0700 |
---|---|---|
committer | Pixel <pixel@nobis-crew.org> | 2010-06-14 23:47:31 -0700 |
commit | 7c0c85a86aa73c0c495523f994f8412e377a8195 (patch) | |
tree | 29929fdc4390224b3a4f8b728d50ae5dfc3589ce /im/src/process | |
parent | 5000908b9b2761854951cea3e7dad90be76ffd59 (diff) |
Upgrading im to 3.6
Diffstat (limited to 'im/src/process')
-rwxr-xr-x | im/src/process/im_analyze.cpp | 23 | ||||
-rwxr-xr-x | im/src/process/im_arithmetic_bin.cpp | 144 | ||||
-rwxr-xr-x | im/src/process/im_color.cpp | 6 | ||||
-rwxr-xr-x | im/src/process/im_geometric.cpp | 37 | ||||
-rwxr-xr-x | im/src/process/im_resize.cpp | 24 |
5 files changed, 201 insertions, 33 deletions
diff --git a/im/src/process/im_analyze.cpp b/im/src/process/im_analyze.cpp index 6fa9405..5a775a0 100755 --- a/im/src/process/im_analyze.cpp +++ b/im/src/process/im_analyze.cpp @@ -2,7 +2,7 @@ * \brief Image Analysis * * See Copyright Notice in im_lib.h - * $Id: im_analyze.cpp,v 1.2 2009/09/28 20:19:09 scuri Exp $ + * $Id: im_analyze.cpp,v 1.5 2010/01/22 19:47:56 scuri Exp $ */ @@ -139,7 +139,7 @@ static int DoAnalyzeFindRegions(int width, int height, imbyte* map, imushort* ne int region_count = 2; // 0- background, 1-border imushort* alias_table = new imushort [MAX_COUNT]; - memset(alias_table, 0, MAX_COUNT); // aliases are all zero at start (not used) + memset(alias_table, 0, MAX_COUNT*sizeof(imushort)); // aliases are all zero at start (not used) for (i = 1; i < height; i++) { @@ -273,7 +273,7 @@ static int DoAnalyzeFindRegionsBorder(int width, int height, imbyte* map, imusho int region_count = 2; // still consider: 0- background, 1-border imushort* alias_table = new imushort [MAX_COUNT]; - memset(alias_table, 0, MAX_COUNT); // aliases are all zero at start (not used) + memset(alias_table, 0, MAX_COUNT*sizeof(imushort)); // aliases are all zero at start (not used) for (i = 0; i < height; i++) { @@ -981,7 +981,7 @@ void imAnalyzeMeasurePerimeter(const imImage* image, float* perim_data, int regi imushort* map = (imushort*)image->data[0]; - memset(perim_data, 0, region_count*sizeof(int)); + memset(perim_data, 0, region_count*sizeof(float)); int width = image->width; int height = image->height; @@ -1203,8 +1203,19 @@ void imProcessRemoveByArea(const imImage* image, imImage* NewImage, int connect, if (end_size == 0) end_size = image->width*image->height; - int outside=0; - if (!inside) outside = 1; + int outside; + if (inside) + { + /* remove from inside */ + inside = 0; + outside = 1; + } + else + { + /* remove from outside */ + inside = 1; + outside = 0; + } int* area_data = (int*)malloc(region_count*sizeof(int)); imAnalyzeMeasureArea(region_image, area_data, region_count); diff --git a/im/src/process/im_arithmetic_bin.cpp b/im/src/process/im_arithmetic_bin.cpp index 494b6c0..575e650 100755 --- a/im/src/process/im_arithmetic_bin.cpp +++ b/im/src/process/im_arithmetic_bin.cpp @@ -2,7 +2,7 @@ * \brief Binary Arithmetic Operations * * See Copyright Notice in im_lib.h - * $Id: im_arithmetic_bin.cpp,v 1.2 2009/10/01 02:56:58 scuri Exp $ + * $Id: im_arithmetic_bin.cpp,v 1.3 2010/01/08 03:49:05 scuri Exp $ */ @@ -262,6 +262,148 @@ void imProcessBlend(const imImage* src_image1, const imImage* src_image2, const } } +#define COMPOSE_OVER(_SRC, _SRC_ALPHA, _DST, _TMP_MULTI, _TMP_ALPHA) (T)(((_SRC_ALPHA)*(_SRC) + (_TMP_MULTI)*(_DST)) / (_TMP_ALPHA)) +#define ALPHA_BLEND(_src,_dst,_alpha) (T)(((_src) * (_alpha) + (_dst) * (max - (_alpha))) / max) + +template <class T, class TA> +static inline T compose_op(const T& v1, const T& v2, const T& alpha1, const T& alpha2, const TA& max) +{ + if (alpha1 != max) /* some transparency */ + { + if (alpha1 != 0) /* source not full transparent */ + { + if (alpha2 == 0) /* destiny full transparent */ + { + return v1; + } + else if (alpha2 == max) /* destiny opaque */ + { + return ALPHA_BLEND(v1, v2, alpha1); + } + else /* (0<alpha2<max && 0<alpha1<max) destiny and source are semi-transparent */ + { + /* Closed Compositing SRC over DST (see smith95a.pdf) */ + /* Colors NOT Premultiplied by Alpha */ + /* DST = SRC * SRC_ALPHA + DST * DST_ALPHA * (1 - SRC_ALPHA) */ + /* DST_ALPHA = SRC_ALPHA + DST_ALPHA * (1 - SRC_ALPHA) */ + /* DST /= DST_ALPHA */ + TA _tmp_multi = alpha2 * (max - alpha1); + TA _tmp_src_alpha = alpha1*max; + TA _tmp_alpha = _tmp_src_alpha + _tmp_multi; + return COMPOSE_OVER(v1, _tmp_src_alpha, v2, _tmp_multi, _tmp_alpha); + } + } + else /* (alpha1 == 0) source full transparent */ + { + return v2; + } + } + else /* (alpha1 == max) source has no alpha = opaque */ + { + return v1; + } +} + +template <class T, class TA> +static inline T compose_alpha_op(const T& alpha1, const T& alpha2, const TA& max) +{ + if (alpha1 != max) /* some transparency */ + { + if (alpha1 != 0) /* source not full transparent */ + { + if (alpha2 == 0) /* destiny full transparent */ + { + return alpha1; + } + else if (alpha2 == max) /* destiny opaque */ + { + /* alpha2 is not changed */ + return alpha2; + } + else /* (0<alpha2<max && 0<alpha1<max) destiny and source are semi-transparent */ + { + /* Closed Compositing SRC over DST (see smith95a.pdf) */ + /* Colors NOT Premultiplied by Alpha */ + /* DST = SRC * SRC_ALPHA + DST * DST_ALPHA * (1 - SRC_ALPHA) */ + /* DST_ALPHA = SRC_ALPHA + DST_ALPHA * (1 - SRC_ALPHA) */ + /* DST /= DST_ALPHA */ + TA _tmp_multi = alpha2 * (max - alpha1); + TA _tmp_src_alpha = alpha1*max; + TA _tmp_alpha = _tmp_src_alpha + _tmp_multi; + return (T)(_tmp_alpha / max); + } + } + else /* (alpha1 == 0) source full transparent */ + { + /* alpha2 is not changed */ + return alpha2; + } + } + else /* (alpha1 == max) source has no alpha = opaque */ + { + return (unsigned char)max; /* set destiny as opaque */ + } +} + +template <class T, class TA> +static void DoCompose(T *map1, T *map2, T *alpha1, T *alpha2, T *map, int count, TA max) +{ + for (int i = 0; i < count; i++) + map[i] = compose_op(map1[i], map2[i], alpha1[i], alpha2[i], max); +} + +template <class T, class TA> +static void DoComposeAlpha(T *alpha1, T *alpha2, T *dst_alpha, int count, TA max) +{ + for (int i = 0; i < count; i++) + dst_alpha[i] = compose_alpha_op(alpha1[i], alpha2[i], max); +} + +void imProcessCompose(const imImage* src_image1, const imImage* src_image2, imImage* dst_image) +{ + int count = src_image1->count, + src_alpha = src_image1->depth; + + if (!src_image1->has_alpha || !src_image2->has_alpha || !dst_image->has_alpha) + return; + + for (int i = 0; i < src_image1->depth; i++) + { + switch(src_image1->data_type) + { + case IM_BYTE: + DoCompose((imbyte*)src_image1->data[i], (imbyte*)src_image2->data[i], (imbyte*)src_image1->data[src_alpha], (imbyte*)src_image2->data[src_alpha], (imbyte*)dst_image->data[i], count, (int)255); + break; + case IM_USHORT: + DoCompose((imushort*)src_image1->data[i], (imushort*)src_image2->data[i], (imushort*)src_image1->data[src_alpha], (imushort*)src_image2->data[src_alpha], (imushort*)dst_image->data[i], count, (int)65535); + break; + case IM_INT: + DoCompose((int*)src_image1->data[i], (int*)src_image2->data[i], (int*)src_image1->data[src_alpha], (int*)src_image2->data[src_alpha], (int*)dst_image->data[i], count, (int)2147483647); + break; + case IM_FLOAT: + DoCompose((float*)src_image1->data[i], (float*)src_image2->data[i], (float*)src_image1->data[src_alpha], (float*)src_image2->data[src_alpha], (float*)dst_image->data[i], count, 1.0f); + break; + } + } + + /* one more for the alpha channel */ + switch(src_image1->data_type) + { + case IM_BYTE: + DoComposeAlpha((imbyte*)src_image1->data[src_alpha], (imbyte*)src_image2->data[src_alpha], (imbyte*)dst_image->data[src_alpha], count, (int)255); + break; + case IM_USHORT: + DoComposeAlpha((imushort*)src_image1->data[src_alpha], (imushort*)src_image2->data[src_alpha], (imushort*)dst_image->data[src_alpha], count, (int)65535); + break; + case IM_INT: + DoComposeAlpha((int*)src_image1->data[src_alpha], (int*)src_image2->data[src_alpha], (int*)dst_image->data[src_alpha], count, (int)2147483647); + break; + case IM_FLOAT: + DoComposeAlpha((float*)src_image1->data[src_alpha], (float*)src_image2->data[src_alpha], (float*)dst_image->data[src_alpha], count, 1.0f); + break; + } +} + static void DoBinaryConstOpCpxReal(imcfloat *map1, float value, imcfloat *map, int count, int op) { int i; diff --git a/im/src/process/im_color.cpp b/im/src/process/im_color.cpp index b27d4b3..29933c4 100755 --- a/im/src/process/im_color.cpp +++ b/im/src/process/im_color.cpp @@ -2,7 +2,7 @@ * \brief Color Processing Operations * * See Copyright Notice in im_lib.h - * $Id: im_color.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $ + * $Id: im_color.cpp,v 1.2 2010/01/06 20:16:30 scuri Exp $ */ #include <im.h> @@ -142,7 +142,7 @@ void imProcessSplitComponents(const imImage* src_image, imImage** dst_image) memcpy(dst_image[0]->data[0], src_image->data[0], src_image->plane_size); memcpy(dst_image[1]->data[0], src_image->data[1], src_image->plane_size); memcpy(dst_image[2]->data[0], src_image->data[2], src_image->plane_size); - if (imColorModeDepth(src_image->color_space) == 4) + if (imColorModeDepth(src_image->color_space) == 4 || src_image->has_alpha) memcpy(dst_image[3]->data[0], src_image->data[3], src_image->plane_size); } @@ -151,7 +151,7 @@ void imProcessMergeComponents(const imImage** src_image, imImage* dst_image) memcpy(dst_image->data[0], src_image[0]->data[0], dst_image->plane_size); memcpy(dst_image->data[1], src_image[1]->data[0], dst_image->plane_size); memcpy(dst_image->data[2], src_image[2]->data[0], dst_image->plane_size); - if (imColorModeDepth(dst_image->color_space) == 4) + if (imColorModeDepth(dst_image->color_space) == 4 || dst_image->has_alpha) memcpy(dst_image->data[3], src_image[3]->data[0], dst_image->plane_size); } diff --git a/im/src/process/im_geometric.cpp b/im/src/process/im_geometric.cpp index a0b5129..d4dbed3 100755 --- a/im/src/process/im_geometric.cpp +++ b/im/src/process/im_geometric.cpp @@ -2,7 +2,7 @@ * \brief Geometric Operations * * See Copyright Notice in im_lib.h - * $Id: im_geometric.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $ + * $Id: im_geometric.cpp,v 1.2 2010/01/07 19:12:53 scuri Exp $ */ @@ -393,7 +393,8 @@ static void InterlaceSplit(int src_width, void imProcessRotate90(const imImage* src_image, imImage* dst_image, int dir) { - for (int i = 0; i < src_image->depth; i++) + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; + for (int i = 0; i < src_depth; i++) { switch(src_image->data_type) { @@ -418,7 +419,8 @@ void imProcessRotate90(const imImage* src_image, imImage* dst_image, int dir) void imProcessRotate180(const imImage* src_image, imImage* dst_image) { - for (int i = 0; i < src_image->depth; i++) + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; + for (int i = 0; i < src_depth; i++) { switch(src_image->data_type) { @@ -446,9 +448,10 @@ int imProcessRadial(const imImage* src_image, imImage* dst_image, float k1, int int ret = 0; int counter = imCounterBegin("Radial Distort"); - imCounterTotal(counter, dst_image->depth*dst_image->height, "Processing..."); + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; + imCounterTotal(counter, src_depth*dst_image->height, "Processing..."); /* size of the destiny image */ - for (int i = 0; i < src_image->depth; i++) + for (int i = 0; i < src_depth; i++) { switch(src_image->data_type) { @@ -483,9 +486,10 @@ int imProcessSwirl(const imImage* src_image, imImage* dst_image, float k, int or int ret = 0; int counter = imCounterBegin("Swirl Distort"); - imCounterTotal(counter, dst_image->depth*dst_image->height, "Processing..."); + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; + imCounterTotal(counter, src_depth*dst_image->height, "Processing..."); /* size of the destiny image */ - for (int i = 0; i < src_image->depth; i++) + for (int i = 0; i < src_depth; i++) { switch(src_image->data_type) { @@ -559,7 +563,8 @@ int imProcessRotate(const imImage* src_image, imImage* dst_image, double cos0, d int ret = 0; int counter = imCounterBegin("Rotate"); - imCounterTotal(counter, dst_image->depth*dst_image->height, "Processing..."); + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; + imCounterTotal(counter, src_depth*dst_image->height, "Processing..."); /* size of the destiny image */ if (src_image->color_space == IM_MAP) { @@ -567,7 +572,7 @@ int imProcessRotate(const imImage* src_image, imImage* dst_image, double cos0, d } else { - for (int i = 0; i < src_image->depth; i++) + for (int i = 0; i < src_depth; i++) { switch(src_image->data_type) { @@ -603,7 +608,8 @@ int imProcessRotateRef(const imImage* src_image, imImage* dst_image, double cos0 int ret = 0; int counter = imCounterBegin("RotateRef"); - imCounterTotal(counter, dst_image->depth*dst_image->height, "Processing..."); + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; + imCounterTotal(counter, src_depth*dst_image->height, "Processing..."); /* size of the destiny image */ if (src_image->color_space == IM_MAP) { @@ -611,7 +617,7 @@ int imProcessRotateRef(const imImage* src_image, imImage* dst_image, double cos0 } else { - for (int i = 0; i < src_image->depth; i++) + for (int i = 0; i < src_depth; i++) { switch(src_image->data_type) { @@ -645,8 +651,9 @@ int imProcessRotateRef(const imImage* src_image, imImage* dst_image, double cos0 void imProcessMirror(const imImage* src_image, imImage* dst_image) { int i; + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; - for (i = 0; i < src_image->depth; i++) + for (i = 0; i < src_depth; i++) { switch(src_image->data_type) { @@ -672,8 +679,9 @@ void imProcessMirror(const imImage* src_image, imImage* dst_image) void imProcessFlip(const imImage* src_image, imImage* dst_image) { int i; + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; - for (i = 0; i < src_image->depth; i++) + for (i = 0; i < src_depth; i++) { switch(src_image->data_type) { @@ -699,8 +707,9 @@ void imProcessFlip(const imImage* src_image, imImage* dst_image) void imProcessInterlaceSplit(const imImage* src_image, imImage* dst_image1, imImage* dst_image2) { int i; + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; - for (i = 0; i < src_image->depth; i++) + for (i = 0; i < src_depth; i++) { switch(src_image->data_type) { diff --git a/im/src/process/im_resize.cpp b/im/src/process/im_resize.cpp index ddf6e47..4dbaa60 100755 --- a/im/src/process/im_resize.cpp +++ b/im/src/process/im_resize.cpp @@ -2,7 +2,7 @@ * \brief Image Resize * * See Copyright Notice in im_lib.h - * $Id: im_resize.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $ + * $Id: im_resize.cpp,v 1.2 2010/01/07 19:12:53 scuri Exp $ */ @@ -106,9 +106,10 @@ int imProcessReduce(const imImage* src_image, imImage* dst_image, int order) int ret = 0; int counter = imCounterBegin("Reduce Size"); const char* int_msg = (order == 1)? "Bilinear Decimation": "Zero Order Decimation"; - imCounterTotal(counter, src_image->depth*dst_image->height, int_msg); + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; + imCounterTotal(counter, src_depth*dst_image->height, int_msg); - for (int i = 0; i < src_image->depth; i++) + for (int i = 0; i < src_depth; i++) { switch(src_image->data_type) { @@ -149,9 +150,10 @@ int imProcessResize(const imImage* src_image, imImage* dst_image, int order) int ret = 0; int counter = imCounterBegin("Resize"); const char* int_msg = (order == 3)? "Bicubic Interpolation": (order == 1)? "Bilinear Interpolation": "Zero Order Interpolation"; - imCounterTotal(counter, src_image->depth*dst_image->height, int_msg); + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; + imCounterTotal(counter, src_depth*dst_image->height, int_msg); - for (int i = 0; i < src_image->depth; i++) + for (int i = 0; i < src_depth; i++) { switch(src_image->data_type) { @@ -219,8 +221,9 @@ static void ReduceBy4(int src_width, void imProcessReduceBy4(const imImage* src_image, imImage* dst_image) { int i; + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; - for (i = 0; i < src_image->depth; i++) + for (i = 0; i < src_depth; i++) { switch(src_image->data_type) { @@ -246,7 +249,8 @@ void imProcessReduceBy4(const imImage* src_image, imImage* dst_image) void imProcessCrop(const imImage* src_image, imImage* dst_image, int xmin, int ymin) { int type_size = imDataTypeSize(src_image->data_type); - for (int i = 0; i < src_image->depth; i++) + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; + for (int i = 0; i < src_depth; i++) { imbyte *src_map = (imbyte*)src_image->data[i]; imbyte *dst_map = (imbyte*)dst_image->data[i]; @@ -269,6 +273,7 @@ void imProcessInsert(const imImage* src_image, const imImage* rgn_image, imImage int dst_offset2 = dst_size1+rgn_image->line_size; int ymax = ymin+rgn_image->height-1; int rgn_size = rgn_image->line_size; + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; if (dst_size2 < 0) { @@ -280,7 +285,7 @@ void imProcessInsert(const imImage* src_image, const imImage* rgn_image, imImage if (ymax > src_image->height-1) ymax = src_image->height-1; - for (int i = 0; i < src_image->depth; i++) + for (int i = 0; i < src_depth; i++) { imbyte *src_map = (imbyte*)src_image->data[i]; imbyte *rgn_map = (imbyte*)rgn_image->data[i]; @@ -315,7 +320,8 @@ void imProcessInsert(const imImage* src_image, const imImage* rgn_image, imImage void imProcessAddMargins(const imImage* src_image, imImage* dst_image, int xmin, int ymin) { int type_size = imDataTypeSize(src_image->data_type); - for (int i = 0; i < src_image->depth; i++) + int src_depth = src_image->has_alpha? src_image->depth+1: src_image->depth; + for (int i = 0; i < src_depth; i++) { imbyte *dst_map = (imbyte*)dst_image->data[i]; imbyte *src_map = (imbyte*)src_image->data[i]; |