comparison mupdf-source/thirdparty/leptonica/src/pixacc.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 /*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
27 /*!
28 * \file pixacc.c
29 * <pre>
30 *
31 * Pixacc creation, destruction
32 * PIXACC *pixaccCreate()
33 * PIXACC *pixaccCreateFromPix()
34 * void pixaccDestroy()
35 *
36 * Pixacc finalization
37 * PIX *pixaccFinal()
38 *
39 * Pixacc accessors
40 * PIX *pixaccGetPix()
41 * l_int32 pixaccGetOffset()
42 *
43 * Pixacc accumulators
44 * l_int32 pixaccAdd()
45 * l_int32 pixaccSubtract()
46 * l_int32 pixaccMultConst()
47 * l_int32 pixaccMultConstAccumulate()
48 *
49 * This is a simple interface for some of the pixel arithmetic operations
50 * in pixarith.c. These are easy to code up, but not as fast as
51 * hand-coded functions that do arithmetic on corresponding pixels.
52 *
53 * Suppose you want to make a linear combination of pix1 and pix2:
54 * pixd = 0.4 * pix1 + 0.6 * pix2
55 * where pix1 and pix2 are the same size and have depth 'd'. Then:
56 * Pixacc *pacc = pixaccCreateFromPix(pix1, 0); // first; addition only
57 * pixaccMultConst(pacc, 0.4);
58 * pixaccMultConstAccumulate(pacc, pix2, 0.6); // Add in 0.6 of the second
59 * pixd = pixaccFinal(pacc, d); // Get the result
60 * pixaccDestroy(&pacc);
61 * </pre>
62 */
63
64 #ifdef HAVE_CONFIG_H
65 #include <config_auto.h>
66 #endif /* HAVE_CONFIG_H */
67
68 #include "allheaders.h"
69 #include "pix_internal.h"
70
71 /*---------------------------------------------------------------------*
72 * Pixacc creation, destruction *
73 *---------------------------------------------------------------------*/
74 /*!
75 * \brief pixaccCreate()
76 *
77 * \param[in] w, h of 32 bpp internal Pix
78 * \param[in] negflag 0 if only positive numbers are involved;
79 * 1 if there will be negative numbers
80 * \return pixacc, or NULL on error
81 *
82 * <pre>
83 * Notes:
84 * (1) Use %negflag = 1 for safety if any negative numbers are going
85 * to be used in the chain of operations. Negative numbers
86 * arise, e.g., by subtracting a pix, or by adding a pix
87 * that has been pre-multiplied by a negative number.
88 * (2) Initializes the internal 32 bpp pix, similarly to the
89 * initialization in pixInitAccumulate().
90 * </pre>
91 */
92 PIXACC *
93 pixaccCreate(l_int32 w,
94 l_int32 h,
95 l_int32 negflag)
96 {
97 PIXACC *pixacc;
98
99 pixacc = (PIXACC *)LEPT_CALLOC(1, sizeof(PIXACC));
100 pixacc->w = w;
101 pixacc->h = h;
102
103 if ((pixacc->pix = pixCreate(w, h, 32)) == NULL) {
104 pixaccDestroy(&pixacc);
105 return (PIXACC *)ERROR_PTR("pix not made", __func__, NULL);
106 }
107
108 if (negflag) {
109 pixacc->offset = 0x40000000;
110 pixSetAllArbitrary(pixacc->pix, pixacc->offset);
111 }
112
113 return pixacc;
114 }
115
116
117 /*!
118 * \brief pixaccCreateFromPix()
119 *
120 * \param[in] pix
121 * \param[in] negflag 0 if only positive numbers are involved;
122 * 1 if there will be negative numbers
123 * \return pixacc, or NULL on error
124 *
125 * <pre>
126 * Notes:
127 * (1) See pixaccCreate()
128 * </pre>
129 */
130 PIXACC *
131 pixaccCreateFromPix(PIX *pix,
132 l_int32 negflag)
133 {
134 l_int32 w, h;
135 PIXACC *pixacc;
136
137 if (!pix)
138 return (PIXACC *)ERROR_PTR("pix not defined", __func__, NULL);
139
140 pixGetDimensions(pix, &w, &h, NULL);
141 pixacc = pixaccCreate(w, h, negflag);
142 pixaccAdd(pixacc, pix);
143 return pixacc;
144 }
145
146
147 /*!
148 * \brief pixaccDestroy()
149 *
150 * \param[in,out] ppixacc will be set to null before returning
151 * \return void
152 *
153 * <pre>
154 * Notes:
155 * (1) Always nulls the input ptr.
156 * </pre>
157 */
158 void
159 pixaccDestroy(PIXACC **ppixacc)
160 {
161 PIXACC *pixacc;
162
163 if (ppixacc == NULL) {
164 L_WARNING("ptr address is NULL!", __func__);
165 return;
166 }
167
168 if ((pixacc = *ppixacc) == NULL)
169 return;
170
171 pixDestroy(&pixacc->pix);
172 LEPT_FREE(pixacc);
173 *ppixacc = NULL;
174 }
175
176
177 /*---------------------------------------------------------------------*
178 * Pixacc finalization *
179 *---------------------------------------------------------------------*/
180 /*!
181 * \brief pixaccFinal()
182 *
183 * \param[in] pixacc
184 * \param[in] outdepth 8, 16 or 32 bpp
185 * \return pixd 8, 16 or 32 bpp, or NULL on error
186 */
187 PIX *
188 pixaccFinal(PIXACC *pixacc,
189 l_int32 outdepth)
190 {
191 if (!pixacc)
192 return (PIX *)ERROR_PTR("pixacc not defined", __func__, NULL);
193
194 return pixFinalAccumulate(pixaccGetPix(pixacc), pixaccGetOffset(pixacc),
195 outdepth);
196 }
197
198
199 /*---------------------------------------------------------------------*
200 * Pixacc accessors *
201 *---------------------------------------------------------------------*/
202 /*!
203 * \brief pixaccGetPix()
204 *
205 * \param[in] pixacc
206 * \return pix, or NULL on error
207 */
208 PIX *
209 pixaccGetPix(PIXACC *pixacc)
210 {
211 if (!pixacc)
212 return (PIX *)ERROR_PTR("pixacc not defined", __func__, NULL);
213 return pixacc->pix;
214 }
215
216
217 /*!
218 * \brief pixaccGetOffset()
219 *
220 * \param[in] pixacc
221 * \return offset, or -1 on error
222 */
223 l_int32
224 pixaccGetOffset(PIXACC *pixacc)
225 {
226 if (!pixacc)
227 return ERROR_INT("pixacc not defined", __func__, -1);
228 return pixacc->offset;
229 }
230
231
232 /*---------------------------------------------------------------------*
233 * Pixacc accumulators *
234 *---------------------------------------------------------------------*/
235 /*!
236 * \brief pixaccAdd()
237 *
238 * \param[in] pixacc
239 * \param[in] pix to be added
240 * \return 0 if OK, 1 on error
241 */
242 l_ok
243 pixaccAdd(PIXACC *pixacc,
244 PIX *pix)
245 {
246 if (!pixacc)
247 return ERROR_INT("pixacc not defined", __func__, 1);
248 if (!pix)
249 return ERROR_INT("pix not defined", __func__, 1);
250 pixAccumulate(pixaccGetPix(pixacc), pix, L_ARITH_ADD);
251 return 0;
252 }
253
254
255 /*!
256 * \brief pixaccSubtract()
257 *
258 * \param[in] pixacc
259 * \param[in] pix to be subtracted
260 * \return 0 if OK, 1 on error
261 */
262 l_ok
263 pixaccSubtract(PIXACC *pixacc,
264 PIX *pix)
265 {
266 if (!pixacc)
267 return ERROR_INT("pixacc not defined", __func__, 1);
268 if (!pix)
269 return ERROR_INT("pix not defined", __func__, 1);
270 pixAccumulate(pixaccGetPix(pixacc), pix, L_ARITH_SUBTRACT);
271 return 0;
272 }
273
274
275 /*!
276 * \brief pixaccMultConst()
277 *
278 * \param[in] pixacc
279 * \param[in] factor
280 * \return 0 if OK, 1 on error
281 */
282 l_ok
283 pixaccMultConst(PIXACC *pixacc,
284 l_float32 factor)
285 {
286 if (!pixacc)
287 return ERROR_INT("pixacc not defined", __func__, 1);
288 pixMultConstAccumulate(pixaccGetPix(pixacc), factor,
289 pixaccGetOffset(pixacc));
290 return 0;
291 }
292
293
294 /*!
295 * \brief pixaccMultConstAccumulate()
296 *
297 * \param[in] pixacc
298 * \param[in] pix
299 * \param[in] factor
300 * \return 0 if OK, 1 on error
301 *
302 * <pre>
303 * Notes:
304 * (1) This creates a temp pix that is %pix multiplied by the
305 * constant %factor. It then adds that into %pixacc.
306 * </pre>
307 */
308 l_ok
309 pixaccMultConstAccumulate(PIXACC *pixacc,
310 PIX *pix,
311 l_float32 factor)
312 {
313 l_int32 w, h, d, negflag;
314 PIX *pixt;
315 PIXACC *pacct;
316
317 if (!pixacc)
318 return ERROR_INT("pixacc not defined", __func__, 1);
319 if (!pix)
320 return ERROR_INT("pix not defined", __func__, 1);
321
322 if (factor == 0.0) return 0;
323
324 pixGetDimensions(pix, &w, &h, &d);
325 negflag = (factor > 0.0) ? 0 : 1;
326 pacct = pixaccCreate(w, h, negflag);
327 pixaccAdd(pacct, pix);
328 pixaccMultConst(pacct, factor);
329 pixt = pixaccFinal(pacct, d);
330 pixaccAdd(pixacc, pixt);
331
332 pixaccDestroy(&pacct);
333 pixDestroy(&pixt);
334 return 0;
335 }