Coverage Report

Created: 2025-12-31 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvips/libvips/arithmetic/statistic.c
Line
Count
Source
1
/* base class for all stats operations
2
 *
3
 * properties:
4
 *  - one image in, single value or matrix out
5
 *  - output depends on whole of input, ie. we have a sink
6
 *
7
 * 24/8/11
8
 *  - from im_avg.c
9
 */
10
11
/*
12
13
  Copyright (C) 1991-2005 The National Gallery
14
15
  This library is free software; you can redistribute it and/or
16
  modify it under the terms of the GNU Lesser General Public
17
  License as published by the Free Software Foundation; either
18
  version 2.1 of the License, or (at your option) any later version.
19
20
  This library is distributed in the hope that it will be useful,
21
  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23
  Lesser General Public License for more details.
24
25
  You should have received a copy of the GNU Lesser General Public
26
  License along with this library; if not, write to the Free Software
27
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28
  02110-1301  USA
29
30
 */
31
32
/*
33
34
  These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
35
36
 */
37
38
/*
39
#define VIPS_DEBUG
40
 */
41
42
#ifdef HAVE_CONFIG_H
43
#include <config.h>
44
#endif /*HAVE_CONFIG_H*/
45
#include <glib/gi18n-lib.h>
46
47
#include <stdio.h>
48
#include <stdlib.h>
49
#include <math.h>
50
51
#include <vips/vips.h>
52
#include <vips/debug.h>
53
#include <vips/internal.h>
54
55
#include "statistic.h"
56
57
396
G_DEFINE_ABSTRACT_TYPE(VipsStatistic, vips_statistic, VIPS_TYPE_OPERATION);
58
396
59
396
static void *
60
396
vips_statistic_scan_start(VipsImage *in, void *a, void *b)
61
66.9k
{
62
66.9k
  VipsStatistic *statistic = VIPS_STATISTIC(a);
63
66.9k
  VipsStatisticClass *class = VIPS_STATISTIC_GET_CLASS(statistic);
64
65
66.9k
  return class->start(statistic);
66
66.9k
}
67
68
static int
69
vips_statistic_scan(VipsRegion *region,
70
  void *seq, void *a, void *b, gboolean *stop)
71
37.3k
{
72
37.3k
  VipsStatistic *statistic = VIPS_STATISTIC(a);
73
37.3k
  VipsStatisticClass *class = VIPS_STATISTIC_GET_CLASS(statistic);
74
75
37.3k
  VipsRect *r = &region->valid;
76
37.3k
  int lsk = VIPS_REGION_LSKIP(region);
77
78
37.3k
  int y;
79
37.3k
  VipsPel *p;
80
81
37.3k
  VIPS_DEBUG_MSG("vips_statistic_scan: %d x %d @ %d x %d\n",
82
37.3k
    r->width, r->height, r->left, r->top);
83
84
37.3k
  p = VIPS_REGION_ADDR(region, r->left, r->top);
85
856k
  for (y = 0; y < r->height; y++) {
86
819k
    if (class->scan(statistic,
87
819k
        seq, r->left, r->top + y, p, r->width))
88
0
      return -1;
89
819k
    p += lsk;
90
819k
  }
91
92
  /* If we've requested stop, pass the message on.
93
   */
94
37.3k
  if (statistic->stop)
95
3.49k
    *stop = TRUE;
96
97
37.3k
  return 0;
98
37.3k
}
99
100
static int
101
vips_statistic_scan_stop(void *seq, void *a, void *b)
102
66.9k
{
103
66.9k
  VipsStatistic *statistic = VIPS_STATISTIC(a);
104
66.9k
  VipsStatisticClass *class = VIPS_STATISTIC_GET_CLASS(statistic);
105
106
66.9k
  return class->stop(statistic, seq);
107
66.9k
}
108
109
static int
110
vips_statistic_build(VipsObject *object)
111
66.9k
{
112
66.9k
  VipsStatistic *statistic = VIPS_STATISTIC(object);
113
66.9k
  VipsStatisticClass *sclass = VIPS_STATISTIC_GET_CLASS(statistic);
114
66.9k
  VipsImage **t = (VipsImage **) vips_object_local_array(object, 2);
115
116
#ifdef DEBUG
117
  printf("vips_statistic_build: ");
118
  vips_object_print_name(object);
119
  printf("\n");
120
#endif /*DEBUG*/
121
122
66.9k
  if (VIPS_OBJECT_CLASS(vips_statistic_parent_class)->build(object))
123
0
    return -1;
124
125
66.9k
  statistic->ready = statistic->in;
126
127
66.9k
  if (vips_image_decode(statistic->ready, &t[0]))
128
0
    return -1;
129
66.9k
  statistic->ready = t[0];
130
131
  /* If there's a format table, cast the input.
132
   */
133
66.9k
  if (sclass->format_table) {
134
0
    if (vips_cast(statistic->ready, &t[1],
135
0
        sclass->format_table[statistic->in->BandFmt], NULL))
136
0
      return -1;
137
0
    statistic->ready = t[1];
138
0
  }
139
140
66.9k
  if (vips_sink(statistic->ready,
141
66.9k
      vips_statistic_scan_start,
142
66.9k
      vips_statistic_scan,
143
66.9k
      vips_statistic_scan_stop,
144
66.9k
      statistic, NULL))
145
43.8k
    return -1;
146
147
23.1k
  return 0;
148
66.9k
}
149
150
static void
151
vips_statistic_class_init(VipsStatisticClass *class)
152
18
{
153
18
  GObjectClass *gobject_class = G_OBJECT_CLASS(class);
154
18
  VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS(class);
155
18
  VipsOperationClass *operation_class = VIPS_OPERATION_CLASS(class);
156
157
18
  gobject_class->set_property = vips_object_set_property;
158
18
  gobject_class->get_property = vips_object_get_property;
159
160
18
  vobject_class->nickname = "statistic";
161
18
  vobject_class->description = _("VIPS statistic operations");
162
18
  vobject_class->build = vips_statistic_build;
163
164
18
  operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
165
166
18
  VIPS_ARG_IMAGE(class, "in", 0,
167
18
    _("Input"),
168
18
    _("Input image"),
169
18
    VIPS_ARGUMENT_REQUIRED_INPUT,
170
18
    G_STRUCT_OFFSET(VipsStatistic, in));
171
18
}
172
173
static void
174
vips_statistic_init(VipsStatistic *statistic)
175
66.9k
{
176
66.9k
}