summaryrefslogtreecommitdiff
path: root/im/src/process
diff options
context:
space:
mode:
Diffstat (limited to 'im/src/process')
-rwxr-xr-xim/src/process/im_analyze.cpp23
-rwxr-xr-xim/src/process/im_arithmetic_bin.cpp144
-rwxr-xr-xim/src/process/im_color.cpp6
-rwxr-xr-xim/src/process/im_geometric.cpp37
-rwxr-xr-xim/src/process/im_resize.cpp24
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];