Coverage Report

Created: 2025-11-16 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvips/libvips/conversion/cache.c
Line
Count
Source
1
/* vips_sink_screen() as an operation.
2
 *
3
 * 13/1/12
4
 *  - from tilecache.c
5
 */
6
7
/*
8
9
  This file is part of VIPS.
10
11
  VIPS is free software; you can redistribute it and/or modify
12
  it under the terms of the GNU Lesser General Public License as published by
13
  the Free Software Foundation; either version 2 of the License, or
14
  (at your option) any later version.
15
16
  This program is distributed in the hope that it will be useful,
17
  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
  GNU Lesser General Public License for more details.
20
21
  You should have received a cache of the GNU Lesser General Public License
22
  along with this program; if not, write to the Free Software
23
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24
  02110-1301  USA
25
26
 */
27
28
/*
29
30
  These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
31
32
 */
33
34
/*
35
#define VIPS_DEBUG
36
 */
37
38
#ifdef HAVE_CONFIG_H
39
#include <config.h>
40
#endif /*HAVE_CONFIG_H*/
41
#include <glib/gi18n-lib.h>
42
43
#include <stdio.h>
44
#include <stdlib.h>
45
#include <string.h>
46
47
#include <vips/vips.h>
48
#include <vips/internal.h>
49
#include <vips/debug.h>
50
51
#include "pconversion.h"
52
53
typedef struct _VipsCache {
54
  VipsConversion parent_instance;
55
56
  VipsImage *in;
57
  int tile_width;
58
  int tile_height;
59
  int max_tiles;
60
} VipsCache;
61
62
typedef VipsConversionClass VipsCacheClass;
63
64
34
G_DEFINE_TYPE(VipsCache, vips_cache, VIPS_TYPE_CONVERSION);
65
34
66
34
static int
67
34
vips_cache_build(VipsObject *object)
68
34
{
69
0
  VipsConversion *conversion = VIPS_CONVERSION(object);
70
0
  VipsCache *cache = (VipsCache *) object;
71
72
0
  VIPS_DEBUG_MSG("vips_cache_build\n");
73
74
0
  if (VIPS_OBJECT_CLASS(vips_cache_parent_class)->build(object))
75
0
    return -1;
76
77
0
  if (vips_sink_screen(cache->in, conversion->out, NULL,
78
0
      cache->tile_width, cache->tile_height, cache->max_tiles,
79
0
      0, NULL, NULL))
80
0
    return -1;
81
82
0
  return 0;
83
0
}
84
85
static void
86
vips_cache_class_init(VipsCacheClass *class)
87
17
{
88
17
  GObjectClass *gobject_class = G_OBJECT_CLASS(class);
89
17
  VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS(class);
90
17
  VipsOperationClass *operation_class = VIPS_OPERATION_CLASS(class);
91
92
17
  VIPS_DEBUG_MSG("vips_cache_class_init\n");
93
94
17
  gobject_class->set_property = vips_object_set_property;
95
17
  gobject_class->get_property = vips_object_get_property;
96
97
17
  vobject_class->nickname = "cache";
98
17
  vobject_class->description = _("cache an image");
99
17
  vobject_class->build = vips_cache_build;
100
101
  /* sinkscreen swallows errors (you don't want to see them when you display
102
   * images), making this operation worse than useless for batch processing.
103
   * Just use tilecache() instead.
104
   */
105
17
  operation_class->flags |= VIPS_OPERATION_DEPRECATED;
106
107
17
  VIPS_ARG_IMAGE(class, "in", 1,
108
17
    _("Input"),
109
17
    _("Input image"),
110
17
    VIPS_ARGUMENT_REQUIRED_INPUT,
111
17
    G_STRUCT_OFFSET(VipsCache, in));
112
113
17
  VIPS_ARG_INT(class, "tile_width", 3,
114
17
    _("Tile width"),
115
17
    _("Tile width in pixels"),
116
17
    VIPS_ARGUMENT_OPTIONAL_INPUT,
117
17
    G_STRUCT_OFFSET(VipsCache, tile_width),
118
17
    1, 1000000, 128);
119
120
17
  VIPS_ARG_INT(class, "tile_height", 3,
121
17
    _("Tile height"),
122
17
    _("Tile height in pixels"),
123
17
    VIPS_ARGUMENT_OPTIONAL_INPUT,
124
17
    G_STRUCT_OFFSET(VipsCache, tile_height),
125
17
    1, 1000000, 128);
126
127
17
  VIPS_ARG_INT(class, "max_tiles", 3,
128
17
    _("Max tiles"),
129
17
    _("Maximum number of tiles to cache"),
130
17
    VIPS_ARGUMENT_OPTIONAL_INPUT,
131
17
    G_STRUCT_OFFSET(VipsCache, max_tiles),
132
17
    -1, 1000000, 250);
133
17
}
134
135
static void
136
vips_cache_init(VipsCache *cache)
137
0
{
138
  /* By default, enough pixels for two 1920 x 1080 displays.
139
   */
140
0
  cache->tile_width = 128;
141
0
  cache->tile_height = 128;
142
0
  cache->max_tiles = 250;
143
0
}
144
145
/**
146
 * vips_cache:
147
 * @in: input image
148
 * @out: (out): output image
149
 * @...: `NULL`-terminated list of optional named arguments
150
 *
151
 * This operation behaves rather like [method@Image.copy] between images
152
 * @in and @out, except that it keeps a cache of computed pixels.
153
 * This cache is made of up to @max_tiles tiles (a value of -1
154
 * means any number of tiles), and each tile is of size @tile_width
155
 * by @tile_height pixels. By default it will cache 250 128 x 128 pixel tiles,
156
 * enough for two 1920 x 1080 images.
157
 *
158
 * This operation is a thin wrapper over [method@Image.sink_screen], see the
159
 * documentation for that operation for details.
160
 *
161
 * It uses a set of background threads to calculate pixels and the various
162
 * active cache operations coordinate so as not to overwhelm your system. When
163
 * a request is made for an area of pixels, the operation will block until all
164
 * of those pixels have been calculated. Pixels are calculated with a set of
165
 * threads.
166
 *
167
 * ::: tip "Optional arguments"
168
 *     * @tile_width: width of tiles in cache
169
 *     * @tile_height: height of tiles in cache
170
 *     * @max_tiles: maximum number of tiles to cache
171
 *
172
 * ::: seealso
173
 *     [method@Image.tilecache].
174
 *
175
 * Returns: 0 on success, -1 on error.
176
 */
177
int
178
vips_cache(VipsImage *in, VipsImage **out, ...)
179
0
{
180
0
  va_list ap;
181
0
  int result;
182
183
0
  va_start(ap, out);
184
0
  result = vips_call_split("cache", ap, in, out);
185
0
  va_end(ap);
186
187
0
  return result;
188
0
}