/src/libvips/libvips/morphology/countlines.c
Line | Count | Source |
1 | | /* count lines |
2 | | * |
3 | | * Copyright: 1990, N. Dessipris. |
4 | | * |
5 | | * Author: Nicos Dessipris |
6 | | * Written on: 02/05/1990 |
7 | | * Modified on : |
8 | | * |
9 | | * 19/9/95 JC |
10 | | * - tidied up |
11 | | * 23/10/10 |
12 | | * - gtk-doc |
13 | | * 17/1/14 |
14 | | * - redone as a class, now just a convenience function |
15 | | */ |
16 | | |
17 | | /* |
18 | | |
19 | | This file is part of VIPS. |
20 | | |
21 | | VIPS is free software; you can redistribute it and/or modify |
22 | | it under the terms of the GNU Lesser General Public License as published by |
23 | | the Free Software Foundation; either version 2 of the License, or |
24 | | (at your option) any later version. |
25 | | |
26 | | This program is distributed in the hope that it will be useful, |
27 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
28 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
29 | | GNU Lesser General Public License for more details. |
30 | | |
31 | | You should have received a copy of the GNU Lesser General Public License |
32 | | along with this program; if not, write to the Free Software |
33 | | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
34 | | 02110-1301 USA |
35 | | |
36 | | */ |
37 | | |
38 | | /* |
39 | | |
40 | | These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk |
41 | | |
42 | | */ |
43 | | |
44 | | /* |
45 | | #define VIPS_DEBUG |
46 | | */ |
47 | | |
48 | | #ifdef HAVE_CONFIG_H |
49 | | #include <config.h> |
50 | | #endif /*HAVE_CONFIG_H*/ |
51 | | #include <glib/gi18n-lib.h> |
52 | | |
53 | | #include <stdio.h> |
54 | | #include <string.h> |
55 | | #include <stdlib.h> |
56 | | |
57 | | #include <vips/vips.h> |
58 | | #include <vips/internal.h> |
59 | | #include <vips/debug.h> |
60 | | |
61 | | #include "pmorphology.h" |
62 | | |
63 | | typedef struct _VipsCountlines { |
64 | | VipsMorphology parent_instance; |
65 | | |
66 | | double nolines; |
67 | | VipsDirection direction; |
68 | | } VipsCountlines; |
69 | | |
70 | | typedef VipsMorphologyClass VipsCountlinesClass; |
71 | | |
72 | 36 | G_DEFINE_TYPE(VipsCountlines, vips_countlines, VIPS_TYPE_MORPHOLOGY); |
73 | 36 | |
74 | 36 | static int |
75 | 36 | vips_countlines_build(VipsObject *object) |
76 | 36 | { |
77 | 0 | VipsMorphology *morphology = VIPS_MORPHOLOGY(object); |
78 | 0 | VipsCountlines *countlines = (VipsCountlines *) object; |
79 | 0 | VipsImage *in = morphology->in; |
80 | 0 | VipsImage **t = (VipsImage **) vips_object_local_array(object, 7); |
81 | |
|
82 | 0 | double nolines; |
83 | |
|
84 | 0 | if (VIPS_OBJECT_CLASS(vips_countlines_parent_class)->build(object)) |
85 | 0 | return -1; |
86 | | |
87 | | /* Compiler warnings. |
88 | | */ |
89 | 0 | nolines = 1; |
90 | |
|
91 | 0 | switch (countlines->direction) { |
92 | 0 | case VIPS_DIRECTION_HORIZONTAL: |
93 | 0 | if (!(t[0] = vips_image_new_matrixv(1, 2, -1.0, 1.0)) || |
94 | 0 | vips_moreeq_const1(in, &t[1], 128, NULL) || |
95 | 0 | vips_conv(t[1], &t[2], t[0], |
96 | 0 | "precision", VIPS_PRECISION_INTEGER, |
97 | 0 | NULL) || |
98 | 0 | vips_project(t[2], &t[3], &t[4], NULL) || |
99 | 0 | vips_avg(t[3], &nolines, NULL)) |
100 | 0 | return -1; |
101 | 0 | break; |
102 | | |
103 | 0 | case VIPS_DIRECTION_VERTICAL: |
104 | 0 | if (!(t[0] = vips_image_new_matrixv(2, 1, -1.0, 1.0)) || |
105 | 0 | vips_moreeq_const1(in, &t[1], 128, NULL) || |
106 | 0 | vips_conv(t[1], &t[2], t[0], |
107 | 0 | "precision", VIPS_PRECISION_INTEGER, |
108 | 0 | NULL) || |
109 | 0 | vips_project(t[2], &t[3], &t[4], NULL) || |
110 | 0 | vips_avg(t[4], &nolines, NULL)) |
111 | 0 | return -1; |
112 | 0 | break; |
113 | | |
114 | 0 | default: |
115 | 0 | g_assert_not_reached(); |
116 | 0 | } |
117 | | |
118 | 0 | g_object_set(object, "nolines", nolines / 255.0, NULL); |
119 | |
|
120 | 0 | return 0; |
121 | 0 | } |
122 | | |
123 | | static void |
124 | | vips_countlines_class_init(VipsCountlinesClass *class) |
125 | 18 | { |
126 | 18 | GObjectClass *gobject_class = G_OBJECT_CLASS(class); |
127 | 18 | VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS(class); |
128 | | |
129 | 18 | VIPS_DEBUG_MSG("vips_countlines_class_init\n"); |
130 | | |
131 | 18 | gobject_class->set_property = vips_object_set_property; |
132 | 18 | gobject_class->get_property = vips_object_get_property; |
133 | | |
134 | 18 | vobject_class->nickname = "countlines"; |
135 | 18 | vobject_class->description = _("count lines in an image"); |
136 | 18 | vobject_class->build = vips_countlines_build; |
137 | | |
138 | 18 | VIPS_ARG_DOUBLE(class, "nolines", 2, |
139 | 18 | _("Nolines"), |
140 | 18 | _("Number of lines"), |
141 | 18 | VIPS_ARGUMENT_REQUIRED_OUTPUT, |
142 | 18 | G_STRUCT_OFFSET(VipsCountlines, nolines), |
143 | 18 | 0, 10000000, 0.0); |
144 | | |
145 | 18 | VIPS_ARG_ENUM(class, "direction", 3, |
146 | 18 | _("Direction"), |
147 | 18 | _("Countlines left-right or up-down"), |
148 | 18 | VIPS_ARGUMENT_REQUIRED_INPUT, |
149 | 18 | G_STRUCT_OFFSET(VipsCountlines, direction), |
150 | 18 | VIPS_TYPE_DIRECTION, VIPS_DIRECTION_HORIZONTAL); |
151 | 18 | } |
152 | | |
153 | | static void |
154 | | vips_countlines_init(VipsCountlines *countlines) |
155 | 0 | { |
156 | 0 | } |
157 | | |
158 | | /** |
159 | | * vips_countlines: (method) |
160 | | * @in: input image |
161 | | * @nolines: (out): output average number of lines |
162 | | * @direction: count lines horizontally or vertically |
163 | | * @...: `NULL`-terminated list of optional named arguments |
164 | | * |
165 | | * Function which calculates the number of transitions |
166 | | * between black and white for the horizontal or the vertical |
167 | | * direction of an image. black<128 , white>=128 |
168 | | * The function calculates the number of transitions for all |
169 | | * Xsize or Ysize and returns the mean of the result |
170 | | * Input should be one band, 8-bit. |
171 | | * |
172 | | * ::: seealso |
173 | | * [method@Image.morph], [method@Image.conv]. |
174 | | * |
175 | | * Returns: 0 on success, -1 on error. |
176 | | */ |
177 | | int |
178 | | vips_countlines(VipsImage *in, double *nolines, |
179 | | VipsDirection direction, ...) |
180 | 0 | { |
181 | 0 | va_list ap; |
182 | 0 | int result; |
183 | |
|
184 | 0 | va_start(ap, direction); |
185 | 0 | result = vips_call_split("countlines", ap, in, nolines, direction); |
186 | 0 | va_end(ap); |
187 | |
|
188 | 0 | return result; |
189 | 0 | } |