Coverage Report

Created: 2026-04-01 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvips/libvips/create/point.c
Line
Count
Source
1
/* base class for point-wise creators
2
 *
3
 * 13/6/13
4
 */
5
6
/*
7
8
  This file is part of VIPS.
9
10
  VIPS is free software; you can redistribute it and/or modify
11
  it under the terms of the GNU Lesser General Public License as published by
12
  the Free Software Foundation; either version 2 of the License, or
13
  (at your option) any later version.
14
15
  This program is distributed in the hope that it will be useful,
16
  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
  GNU Lesser General Public License for more details.
19
20
  You should have received a copy of the GNU Lesser General Public License
21
  along with this program; if not, write to the Free Software
22
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23
  02110-1301  USA
24
25
 */
26
27
/*
28
29
  These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
30
31
 */
32
33
/*
34
#define VIPS_DEBUG
35
 */
36
37
#ifdef HAVE_CONFIG_H
38
#include <config.h>
39
#endif /*HAVE_CONFIG_H*/
40
#include <glib/gi18n-lib.h>
41
42
#include <stdio.h>
43
#include <string.h>
44
#include <stdlib.h>
45
#include <math.h>
46
47
#include <vips/vips.h>
48
49
#include "pcreate.h"
50
#include "point.h"
51
52
190
G_DEFINE_ABSTRACT_TYPE(VipsPoint, vips_point, VIPS_TYPE_CREATE);
53
190
54
190
static int
55
190
vips_point_gen(VipsRegion *out_region,
56
190
  void *seq, void *a, void *b, gboolean *stop)
57
1.46k
{
58
1.46k
  VipsPoint *point = (VipsPoint *) a;
59
1.46k
  VipsPointClass *class = VIPS_POINT_GET_CLASS(point);
60
1.46k
  VipsRect *r = &out_region->valid;
61
62
1.46k
  int x, y;
63
64
23.8k
  for (y = 0; y < r->height; y++) {
65
22.3k
    int ay = r->top + y;
66
22.3k
    float *q = (float *) VIPS_REGION_ADDR(out_region, r->left, ay);
67
68
168k
    for (x = 0; x < r->width; x++)
69
146k
      q[x] = class->point(point, r->left + x, ay);
70
22.3k
  }
71
72
1.46k
  return 0;
73
1.46k
}
74
75
static int
76
vips_point_build(VipsObject *object)
77
109
{
78
109
  VipsCreate *create = VIPS_CREATE(object);
79
109
  VipsPoint *point = VIPS_POINT(object);
80
109
  VipsPointClass *class = VIPS_POINT_GET_CLASS(point);
81
109
  VipsImage **t = (VipsImage **) vips_object_local_array(object, 4);
82
83
109
  VipsImage *in;
84
85
109
  if (VIPS_OBJECT_CLASS(vips_point_parent_class)->build(object))
86
7
    return -1;
87
88
102
  t[0] = vips_image_new();
89
102
  vips_image_init_fields(t[0],
90
102
    point->width, point->height, 1,
91
102
    VIPS_FORMAT_FLOAT, VIPS_CODING_NONE, class->interpretation,
92
102
    1.0, 1.0);
93
102
  if (vips_image_pipelinev(t[0], VIPS_DEMAND_STYLE_ANY, NULL) ||
94
102
    vips_image_generate(t[0],
95
102
      NULL, vips_point_gen, NULL, point, NULL))
96
0
    return -1;
97
102
  in = t[0];
98
99
102
  if (point->uchar) {
100
0
    float min = class->min;
101
0
    float max = class->max;
102
0
    float range = max - min;
103
104
0
    if (vips_linear1(in, &t[2],
105
0
        255.0 / range, -min * 255.0 / range,
106
0
        "uchar", TRUE,
107
0
        NULL))
108
0
      return -1;
109
0
    in = t[2];
110
111
    /* We don't want FOURIER or whatever in this case.
112
     */
113
0
    in->Type = VIPS_INTERPRETATION_MULTIBAND;
114
0
  }
115
116
102
  if (vips_image_write(in, create->out))
117
0
    return -1;
118
119
102
  return 0;
120
102
}
121
122
static void
123
vips_point_class_init(VipsPointClass *class)
124
19
{
125
19
  GObjectClass *gobject_class = G_OBJECT_CLASS(class);
126
19
  VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS(class);
127
128
19
  gobject_class->set_property = vips_object_set_property;
129
19
  gobject_class->get_property = vips_object_get_property;
130
131
19
  vobject_class->nickname = "point";
132
19
  vobject_class->description = _("make a point image");
133
19
  vobject_class->build = vips_point_build;
134
135
19
  class->point = NULL;
136
19
  class->min = -1.0F;
137
19
  class->max = 1.0F;
138
19
  class->interpretation = VIPS_INTERPRETATION_MULTIBAND;
139
140
19
  VIPS_ARG_INT(class, "width", 2,
141
19
    _("Width"),
142
19
    _("Image width in pixels"),
143
19
    VIPS_ARGUMENT_REQUIRED_INPUT,
144
19
    G_STRUCT_OFFSET(VipsPoint, width),
145
19
    1, VIPS_MAX_COORD, 1);
146
147
19
  VIPS_ARG_INT(class, "height", 3,
148
19
    _("Height"),
149
19
    _("Image height in pixels"),
150
19
    VIPS_ARGUMENT_REQUIRED_INPUT,
151
19
    G_STRUCT_OFFSET(VipsPoint, height),
152
19
    1, VIPS_MAX_COORD, 1);
153
154
19
  VIPS_ARG_BOOL(class, "uchar", 4,
155
19
    _("Uchar"),
156
19
    _("Output an unsigned char image"),
157
19
    VIPS_ARGUMENT_OPTIONAL_INPUT,
158
19
    G_STRUCT_OFFSET(VipsPoint, uchar),
159
19
    FALSE);
160
19
}
161
162
static void
163
vips_point_init(VipsPoint *point)
164
121
{
165
121
}