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 <vips/intl.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 G_DEFINE_TYPE( VipsCountlines, vips_countlines, VIPS_TYPE_MORPHOLOGY );
73
74 static int
vips_countlines_build(VipsObject * object)75 vips_countlines_build( VipsObject *object )
76 {
77 VipsMorphology *morphology = VIPS_MORPHOLOGY( object );
78 VipsCountlines *countlines = (VipsCountlines *) object;
79 VipsImage *in = morphology->in;
80 VipsImage **t = (VipsImage **) vips_object_local_array( object, 7 );
81
82 double nolines;
83
84 if( VIPS_OBJECT_CLASS( vips_countlines_parent_class )->build( object ) )
85 return( -1 );
86
87 /* Compiler warnings.
88 */
89 nolines = 1;
90
91 switch( countlines->direction ) {
92 case VIPS_DIRECTION_HORIZONTAL:
93 if( !(t[0] = vips_image_new_matrixv( 1, 2, -1.0, 1.0 )) ||
94 vips_moreeq_const1( in, &t[1], 128, NULL ) ||
95 vips_conv( t[1], &t[2], t[0],
96 "precision", VIPS_PRECISION_INTEGER,
97 NULL ) ||
98 vips_project( t[2], &t[3], &t[4], NULL ) ||
99 vips_avg( t[3], &nolines, NULL ) )
100 return( -1 );
101 break;
102
103 case VIPS_DIRECTION_VERTICAL:
104 if( !(t[0] = vips_image_new_matrixv( 2, 1, -1.0, 1.0 )) ||
105 vips_moreeq_const1( in, &t[1], 128, NULL ) ||
106 vips_conv( t[1], &t[2], t[0],
107 "precision", VIPS_PRECISION_INTEGER,
108 NULL ) ||
109 vips_project( t[2], &t[3], &t[4], NULL ) ||
110 vips_avg( t[4], &nolines, NULL ) )
111 return( -1 );
112 break;
113
114 default:
115 g_assert_not_reached();
116 }
117
118 g_object_set( object, "nolines", nolines / 255.0, NULL );
119
120 return( 0 );
121 }
122
123 static void
vips_countlines_class_init(VipsCountlinesClass * class)124 vips_countlines_class_init( VipsCountlinesClass *class )
125 {
126 GObjectClass *gobject_class = G_OBJECT_CLASS( class );
127 VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
128
129 VIPS_DEBUG_MSG( "vips_countlines_class_init\n" );
130
131 gobject_class->set_property = vips_object_set_property;
132 gobject_class->get_property = vips_object_get_property;
133
134 vobject_class->nickname = "countlines";
135 vobject_class->description = _( "count lines in an image" );
136 vobject_class->build = vips_countlines_build;
137
138 VIPS_ARG_DOUBLE( class, "nolines", 2,
139 _( "Nolines" ),
140 _( "Number of lines" ),
141 VIPS_ARGUMENT_REQUIRED_OUTPUT,
142 G_STRUCT_OFFSET( VipsCountlines, nolines ),
143 0, 10000000, 0.0 );
144
145 VIPS_ARG_ENUM( class, "direction", 3,
146 _( "direction" ),
147 _( "Countlines left-right or up-down" ),
148 VIPS_ARGUMENT_REQUIRED_INPUT,
149 G_STRUCT_OFFSET( VipsCountlines, direction ),
150 VIPS_TYPE_DIRECTION, VIPS_DIRECTION_HORIZONTAL );
151
152 }
153
154 static void
vips_countlines_init(VipsCountlines * countlines)155 vips_countlines_init( VipsCountlines *countlines )
156 {
157 }
158
159 /**
160 * vips_countlines: (method)
161 * @in: input image
162 * @nolines: (out): output average number of lines
163 * @direction: count lines horizontally or vertically
164 * @...: %NULL-terminated list of optional named arguments
165 *
166 * Function which calculates the number of transitions
167 * between black and white for the horizontal or the vertical
168 * direction of an image. black<128 , white>=128
169 * The function calculates the number of transitions for all
170 * Xsize or Ysize and returns the mean of the result
171 * Input should be one band, 8-bit.
172 *
173 * See also: vips_morph(), vips_conv().
174 *
175 * Returns: 0 on success, -1 on error.
176 */
177 int
vips_countlines(VipsImage * in,double * nolines,VipsDirection direction,...)178 vips_countlines( VipsImage *in, double *nolines,
179 VipsDirection direction, ... )
180 {
181 va_list ap;
182 int result;
183
184 va_start( ap, direction );
185 result = vips_call_split( "countlines", ap, in, nolines, direction );
186 va_end( ap );
187
188 return( result );
189 }
190