Coverage Report

Created: 2025-02-19 06:30

/src/cairo/subprojects/pixman-0.43.4/pixman/pixman-bits-image.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
3
 *             2005 Lars Knoll & Zack Rusin, Trolltech
4
 *             2008 Aaron Plattner, NVIDIA Corporation
5
 * Copyright © 2000 SuSE, Inc.
6
 * Copyright © 2007, 2009 Red Hat, Inc.
7
 * Copyright © 2008 André Tupinambá <andrelrt@gmail.com>
8
 *
9
 * Permission to use, copy, modify, distribute, and sell this software and its
10
 * documentation for any purpose is hereby granted without fee, provided that
11
 * the above copyright notice appear in all copies and that both that
12
 * copyright notice and this permission notice appear in supporting
13
 * documentation, and that the name of Keith Packard not be used in
14
 * advertising or publicity pertaining to distribution of the software without
15
 * specific, written prior permission.  Keith Packard makes no
16
 * representations about the suitability of this software for any purpose.  It
17
 * is provided "as is" without express or implied warranty.
18
 *
19
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
20
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
21
 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
22
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
24
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
25
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26
 * SOFTWARE.
27
 */
28
29
#ifdef HAVE_CONFIG_H
30
#include <pixman-config.h>
31
#endif
32
#include <stdio.h>
33
#include <stdlib.h>
34
#include <string.h>
35
#include "pixman-private.h"
36
#include "pixman-combine32.h"
37
#include "pixman-inlines.h"
38
#include "dither/blue-noise-64x64.h"
39
40
/* Fetch functions */
41
42
static force_inline void
43
fetch_pixel_no_alpha_32 (bits_image_t *image,
44
       int x, int y, pixman_bool_t check_bounds,
45
       void *out)
46
0
{
47
0
    uint32_t *ret = out;
48
49
0
    if (check_bounds &&
50
0
  (x < 0 || x >= image->width || y < 0 || y >= image->height))
51
0
  *ret = 0;
52
0
    else
53
0
  *ret = image->fetch_pixel_32 (image, x, y);
54
0
}
55
56
static force_inline void
57
fetch_pixel_no_alpha_float (bits_image_t *image,
58
          int x, int y, pixman_bool_t check_bounds,
59
          void *out)
60
0
{
61
0
    argb_t *ret = out;
62
63
0
    if (check_bounds &&
64
0
  (x < 0 || x >= image->width || y < 0 || y >= image->height))
65
0
  ret->a = ret->r = ret->g = ret->b = 0.f;
66
0
    else
67
0
  *ret = image->fetch_pixel_float (image, x, y);
68
0
}
69
70
typedef void (* get_pixel_t) (bits_image_t *image,
71
            int x, int y, pixman_bool_t check_bounds, void *out);
72
73
static force_inline void
74
bits_image_fetch_pixel_nearest (bits_image_t   *image,
75
        pixman_fixed_t  x,
76
        pixman_fixed_t  y,
77
        get_pixel_t get_pixel,
78
        void         *out)
79
0
{
80
0
    int x0 = pixman_fixed_to_int (x - pixman_fixed_e);
81
0
    int y0 = pixman_fixed_to_int (y - pixman_fixed_e);
82
83
0
    if (image->common.repeat != PIXMAN_REPEAT_NONE)
84
0
    {
85
0
  repeat (image->common.repeat, &x0, image->width);
86
0
  repeat (image->common.repeat, &y0, image->height);
87
88
0
  get_pixel (image, x0, y0, FALSE, out);
89
0
    }
90
0
    else
91
0
    {
92
0
  get_pixel (image, x0, y0, TRUE, out);
93
0
    }
94
0
}
95
96
static force_inline void
97
bits_image_fetch_pixel_bilinear_32 (bits_image_t   *image,
98
            pixman_fixed_t  x,
99
            pixman_fixed_t  y,
100
            get_pixel_t     get_pixel,
101
            void     *out)
102
0
{
103
0
    pixman_repeat_t repeat_mode = image->common.repeat;
104
0
    int width = image->width;
105
0
    int height = image->height;
106
0
    int x1, y1, x2, y2;
107
0
    uint32_t tl, tr, bl, br;
108
0
    int32_t distx, disty;
109
0
    uint32_t *ret = out;
110
111
0
    x1 = x - pixman_fixed_1 / 2;
112
0
    y1 = y - pixman_fixed_1 / 2;
113
114
0
    distx = pixman_fixed_to_bilinear_weight (x1);
115
0
    disty = pixman_fixed_to_bilinear_weight (y1);
116
117
0
    x1 = pixman_fixed_to_int (x1);
118
0
    y1 = pixman_fixed_to_int (y1);
119
0
    x2 = x1 + 1;
120
0
    y2 = y1 + 1;
121
122
0
    if (repeat_mode != PIXMAN_REPEAT_NONE)
123
0
    {
124
0
  repeat (repeat_mode, &x1, width);
125
0
  repeat (repeat_mode, &y1, height);
126
0
  repeat (repeat_mode, &x2, width);
127
0
  repeat (repeat_mode, &y2, height);
128
129
0
  get_pixel (image, x1, y1, FALSE, &tl);
130
0
  get_pixel (image, x2, y1, FALSE, &tr);
131
0
  get_pixel (image, x1, y2, FALSE, &bl);
132
0
  get_pixel (image, x2, y2, FALSE, &br);
133
0
    }
134
0
    else
135
0
    {
136
0
  get_pixel (image, x1, y1, TRUE, &tl);
137
0
  get_pixel (image, x2, y1, TRUE, &tr);
138
0
  get_pixel (image, x1, y2, TRUE, &bl);
139
0
  get_pixel (image, x2, y2, TRUE, &br);
140
0
    }
141
142
0
    *ret = bilinear_interpolation (tl, tr, bl, br, distx, disty);
143
0
}
144
145
static force_inline void
146
bits_image_fetch_pixel_bilinear_float (bits_image_t   *image,
147
               pixman_fixed_t  x,
148
               pixman_fixed_t  y,
149
               get_pixel_t     get_pixel,
150
               void       *out)
151
0
{
152
0
    pixman_repeat_t repeat_mode = image->common.repeat;
153
0
    int width = image->width;
154
0
    int height = image->height;
155
0
    int x1, y1, x2, y2;
156
0
    argb_t tl, tr, bl, br;
157
0
    float distx, disty;
158
0
    argb_t *ret = out;
159
160
0
    x1 = x - pixman_fixed_1 / 2;
161
0
    y1 = y - pixman_fixed_1 / 2;
162
163
0
    distx = ((float)pixman_fixed_fraction(x1)) / 65536.f;
164
0
    disty = ((float)pixman_fixed_fraction(y1)) / 65536.f;
165
166
0
    x1 = pixman_fixed_to_int (x1);
167
0
    y1 = pixman_fixed_to_int (y1);
168
0
    x2 = x1 + 1;
169
0
    y2 = y1 + 1;
170
171
0
    if (repeat_mode != PIXMAN_REPEAT_NONE)
172
0
    {
173
0
  repeat (repeat_mode, &x1, width);
174
0
  repeat (repeat_mode, &y1, height);
175
0
  repeat (repeat_mode, &x2, width);
176
0
  repeat (repeat_mode, &y2, height);
177
178
0
  get_pixel (image, x1, y1, FALSE, &tl);
179
0
  get_pixel (image, x2, y1, FALSE, &tr);
180
0
  get_pixel (image, x1, y2, FALSE, &bl);
181
0
  get_pixel (image, x2, y2, FALSE, &br);
182
0
    }
183
0
    else
184
0
    {
185
0
  get_pixel (image, x1, y1, TRUE, &tl);
186
0
  get_pixel (image, x2, y1, TRUE, &tr);
187
0
  get_pixel (image, x1, y2, TRUE, &bl);
188
0
  get_pixel (image, x2, y2, TRUE, &br);
189
0
    }
190
191
0
    *ret = bilinear_interpolation_float (tl, tr, bl, br, distx, disty);
192
0
}
193
194
static force_inline void accum_32(unsigned int *satot, unsigned int *srtot,
195
          unsigned int *sgtot, unsigned int *sbtot,
196
          const void *p, pixman_fixed_t f)
197
0
{
198
0
    uint32_t pixel = *(uint32_t *)p;
199
200
0
    *srtot += (int)RED_8 (pixel) * f;
201
0
    *sgtot += (int)GREEN_8 (pixel) * f;
202
0
    *sbtot += (int)BLUE_8 (pixel) * f;
203
0
    *satot += (int)ALPHA_8 (pixel) * f;
204
0
}
205
206
static force_inline void reduce_32(unsigned int satot, unsigned int srtot,
207
           unsigned int sgtot, unsigned int sbtot,
208
                                   void *p)
209
0
{
210
0
    uint32_t *ret = p;
211
212
0
    satot = (int32_t)(satot + 0x8000) / 65536;
213
0
    srtot = (int32_t)(srtot + 0x8000) / 65536;
214
0
    sgtot = (int32_t)(sgtot + 0x8000) / 65536;
215
0
    sbtot = (int32_t)(sbtot + 0x8000) / 65536;
216
217
0
    satot = CLIP ((int32_t)satot, 0, 0xff);
218
0
    srtot = CLIP ((int32_t)srtot, 0, 0xff);
219
0
    sgtot = CLIP ((int32_t)sgtot, 0, 0xff);
220
0
    sbtot = CLIP ((int32_t)sbtot, 0, 0xff);
221
222
0
    *ret = ((satot << 24) | (srtot << 16) | (sgtot <<  8) | (sbtot));
223
0
}
224
225
static force_inline void accum_float(unsigned int *satot, unsigned int *srtot,
226
             unsigned int *sgtot, unsigned int *sbtot,
227
             const void *p, pixman_fixed_t f)
228
0
{
229
0
    const argb_t *pixel = p;
230
231
0
    *satot += pixel->a * f;
232
0
    *srtot += pixel->r * f;
233
0
    *sgtot += pixel->g * f;
234
0
    *sbtot += pixel->b * f;
235
0
}
236
237
static force_inline void reduce_float(unsigned int satot, unsigned int srtot,
238
              unsigned int sgtot, unsigned int sbtot,
239
              void *p)
240
0
{
241
0
    argb_t *ret = p;
242
243
0
    ret->a = CLIP ((int32_t)satot / 65536.f, 0.f, 1.f);
244
0
    ret->r = CLIP ((int32_t)srtot / 65536.f, 0.f, 1.f);
245
0
    ret->g = CLIP ((int32_t)sgtot / 65536.f, 0.f, 1.f);
246
0
    ret->b = CLIP ((int32_t)sbtot / 65536.f, 0.f, 1.f);
247
0
}
248
249
typedef void (* accumulate_pixel_t) (unsigned int *satot, unsigned int *srtot,
250
             unsigned int *sgtot, unsigned int *sbtot,
251
             const void *pixel, pixman_fixed_t f);
252
253
typedef void (* reduce_pixel_t) (unsigned int satot, unsigned int srtot,
254
         unsigned int sgtot, unsigned int sbtot,
255
                                 void *out);
256
257
static force_inline void
258
bits_image_fetch_pixel_convolution (bits_image_t   *image,
259
            pixman_fixed_t  x,
260
            pixman_fixed_t  y,
261
            get_pixel_t     get_pixel,
262
            void        *out,
263
            accumulate_pixel_t accum,
264
            reduce_pixel_t reduce)
265
0
{
266
0
    pixman_fixed_t *params = image->common.filter_params;
267
0
    int x_off = (params[0] - pixman_fixed_1) >> 1;
268
0
    int y_off = (params[1] - pixman_fixed_1) >> 1;
269
0
    int32_t cwidth = pixman_fixed_to_int (params[0]);
270
0
    int32_t cheight = pixman_fixed_to_int (params[1]);
271
0
    int32_t i, j, x1, x2, y1, y2;
272
0
    pixman_repeat_t repeat_mode = image->common.repeat;
273
0
    int width = image->width;
274
0
    int height = image->height;
275
0
    unsigned int srtot, sgtot, sbtot, satot;
276
277
0
    params += 2;
278
279
0
    x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
280
0
    y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
281
0
    x2 = x1 + cwidth;
282
0
    y2 = y1 + cheight;
283
284
0
    srtot = sgtot = sbtot = satot = 0;
285
286
0
    for (i = y1; i < y2; ++i)
287
0
    {
288
0
  for (j = x1; j < x2; ++j)
289
0
  {
290
0
      int rx = j;
291
0
      int ry = i;
292
293
0
      pixman_fixed_t f = *params;
294
295
0
      if (f)
296
0
      {
297
    /* Must be big enough to hold a argb_t */
298
0
    argb_t pixel;
299
300
0
    if (repeat_mode != PIXMAN_REPEAT_NONE)
301
0
    {
302
0
        repeat (repeat_mode, &rx, width);
303
0
        repeat (repeat_mode, &ry, height);
304
305
0
        get_pixel (image, rx, ry, FALSE, &pixel);
306
0
    }
307
0
    else
308
0
    {
309
0
        get_pixel (image, rx, ry, TRUE, &pixel);
310
0
    }
311
312
0
    accum (&satot, &srtot, &sgtot, &sbtot, &pixel, f);
313
0
      }
314
315
0
      params++;
316
0
  }
317
0
    }
318
319
0
    reduce (satot, srtot, sgtot, sbtot, out);
320
0
}
321
322
static void
323
bits_image_fetch_pixel_separable_convolution (bits_image_t  *image,
324
                pixman_fixed_t x,
325
                pixman_fixed_t y,
326
                get_pixel_t    get_pixel,
327
                void      *out,
328
                accumulate_pixel_t accum,
329
                reduce_pixel_t     reduce)
330
0
{
331
0
    pixman_fixed_t *params = image->common.filter_params;
332
0
    pixman_repeat_t repeat_mode = image->common.repeat;
333
0
    int width = image->width;
334
0
    int height = image->height;
335
0
    int cwidth = pixman_fixed_to_int (params[0]);
336
0
    int cheight = pixman_fixed_to_int (params[1]);
337
0
    int x_phase_bits = pixman_fixed_to_int (params[2]);
338
0
    int y_phase_bits = pixman_fixed_to_int (params[3]);
339
0
    int x_phase_shift = 16 - x_phase_bits;
340
0
    int y_phase_shift = 16 - y_phase_bits;
341
0
    int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1;
342
0
    int y_off = ((cheight << 16) - pixman_fixed_1) >> 1;
343
0
    pixman_fixed_t *y_params;
344
0
    unsigned int srtot, sgtot, sbtot, satot;
345
0
    int32_t x1, x2, y1, y2;
346
0
    int32_t px, py;
347
0
    int i, j;
348
349
    /* Round x and y to the middle of the closest phase before continuing. This
350
     * ensures that the convolution matrix is aligned right, since it was
351
     * positioned relative to a particular phase (and not relative to whatever
352
     * exact fraction we happen to get here).
353
     */
354
0
    x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
355
0
    y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
356
357
0
    px = (x & 0xffff) >> x_phase_shift;
358
0
    py = (y & 0xffff) >> y_phase_shift;
359
360
0
    y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight;
361
362
0
    x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
363
0
    y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
364
0
    x2 = x1 + cwidth;
365
0
    y2 = y1 + cheight;
366
367
0
    srtot = sgtot = sbtot = satot = 0;
368
369
0
    for (i = y1; i < y2; ++i)
370
0
    {
371
0
        pixman_fixed_48_16_t fy = *y_params++;
372
0
        pixman_fixed_t *x_params = params + 4 + px * cwidth;
373
374
0
        if (fy)
375
0
        {
376
0
            for (j = x1; j < x2; ++j)
377
0
            {
378
0
                pixman_fixed_t fx = *x_params++;
379
0
    int rx = j;
380
0
    int ry = i;
381
382
0
                if (fx)
383
0
                {
384
                    /* Must be big enough to hold a argb_t */
385
0
                    argb_t pixel;
386
0
                    pixman_fixed_t f;
387
388
0
                    if (repeat_mode != PIXMAN_REPEAT_NONE)
389
0
                    {
390
0
                        repeat (repeat_mode, &rx, width);
391
0
                        repeat (repeat_mode, &ry, height);
392
393
0
                        get_pixel (image, rx, ry, FALSE, &pixel);
394
0
                    }
395
0
                    else
396
0
                    {
397
0
                        get_pixel (image, rx, ry, TRUE, &pixel);
398
0
        }
399
400
0
                    f = (fy * fx + 0x8000) >> 16;
401
402
0
        accum(&satot, &srtot, &sgtot, &sbtot, &pixel, f);
403
0
                }
404
0
            }
405
0
  }
406
0
    }
407
408
409
0
    reduce(satot, srtot, sgtot, sbtot, out);
410
0
}
411
412
static force_inline void
413
bits_image_fetch_pixel_filtered (bits_image_t  *image,
414
         pixman_bool_t  wide,
415
         pixman_fixed_t x,
416
         pixman_fixed_t y,
417
         get_pixel_t    get_pixel,
418
         void          *out)
419
0
{
420
0
    switch (image->common.filter)
421
0
    {
422
0
    case PIXMAN_FILTER_NEAREST:
423
0
    case PIXMAN_FILTER_FAST:
424
0
  bits_image_fetch_pixel_nearest (image, x, y, get_pixel, out);
425
0
  break;
426
427
0
    case PIXMAN_FILTER_BILINEAR:
428
0
    case PIXMAN_FILTER_GOOD:
429
0
    case PIXMAN_FILTER_BEST:
430
0
  if (wide)
431
0
      bits_image_fetch_pixel_bilinear_float (image, x, y, get_pixel, out);
432
0
  else
433
0
      bits_image_fetch_pixel_bilinear_32 (image, x, y, get_pixel, out);
434
0
  break;
435
436
0
    case PIXMAN_FILTER_CONVOLUTION:
437
0
  if (wide)
438
0
  {
439
0
      bits_image_fetch_pixel_convolution (image, x, y,
440
0
            get_pixel, out,
441
0
            accum_float,
442
0
            reduce_float);
443
0
  }
444
0
  else
445
0
  {
446
0
      bits_image_fetch_pixel_convolution (image, x, y,
447
0
            get_pixel, out,
448
0
            accum_32, reduce_32);
449
0
  }
450
0
  break;
451
452
0
    case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
453
0
  if (wide)
454
0
  {
455
0
      bits_image_fetch_pixel_separable_convolution (image, x, y,
456
0
                get_pixel, out,
457
0
                accum_float,
458
0
                reduce_float);
459
0
  }
460
0
  else
461
0
  {
462
0
      bits_image_fetch_pixel_separable_convolution (image, x, y,
463
0
                get_pixel, out,
464
0
                accum_32, reduce_32);
465
0
  }
466
0
        break;
467
468
0
    default:
469
0
  assert (0);
470
0
        break;
471
0
    }
472
0
}
473
474
static uint32_t *
475
__bits_image_fetch_affine_no_alpha (pixman_iter_t *  iter,
476
            pixman_bool_t    wide,
477
            const uint32_t * mask)
478
0
{
479
0
    pixman_image_t *image  = iter->image;
480
0
    int             offset = iter->x;
481
0
    int             line   = iter->y++;
482
0
    int             width  = iter->width;
483
0
    uint32_t *      buffer = iter->buffer;
484
485
0
    const uint32_t wide_zero[4] = {0};
486
0
    pixman_fixed_t x, y;
487
0
    pixman_fixed_t ux, uy;
488
0
    pixman_vector_t v;
489
0
    int i;
490
0
    get_pixel_t get_pixel =
491
0
  wide ? fetch_pixel_no_alpha_float : fetch_pixel_no_alpha_32;
492
493
    /* reference point is the center of the pixel */
494
0
    v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
495
0
    v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
496
0
    v.vector[2] = pixman_fixed_1;
497
498
0
    if (image->common.transform)
499
0
    {
500
0
  if (!pixman_transform_point_3d (image->common.transform, &v))
501
0
      return iter->buffer;
502
503
0
  ux = image->common.transform->matrix[0][0];
504
0
  uy = image->common.transform->matrix[1][0];
505
0
    }
506
0
    else
507
0
    {
508
0
  ux = pixman_fixed_1;
509
0
  uy = 0;
510
0
    }
511
512
0
    x = v.vector[0];
513
0
    y = v.vector[1];
514
515
0
    for (i = 0; i < width; ++i)
516
0
    {
517
0
  if (!mask || (!wide && mask[i]) ||
518
0
      (wide && memcmp(&mask[4 * i], wide_zero, 16) != 0))
519
0
  {
520
0
      bits_image_fetch_pixel_filtered (
521
0
    &image->bits, wide, x, y, get_pixel, buffer);
522
0
  }
523
524
0
  x += ux;
525
0
  y += uy;
526
0
  buffer += wide ? 4 : 1;
527
0
    }
528
529
0
    return iter->buffer;
530
0
}
531
532
static uint32_t *
533
bits_image_fetch_affine_no_alpha_32 (pixman_iter_t  *iter,
534
             const uint32_t *mask)
535
0
{
536
0
    return __bits_image_fetch_affine_no_alpha(iter, FALSE, mask);
537
0
}
538
539
static uint32_t *
540
bits_image_fetch_affine_no_alpha_float (pixman_iter_t  *iter,
541
          const uint32_t *mask)
542
0
{
543
0
    return __bits_image_fetch_affine_no_alpha(iter, TRUE, mask);
544
0
}
545
546
/* General fetcher */
547
static force_inline void
548
fetch_pixel_general_32 (bits_image_t *image,
549
      int x, int y, pixman_bool_t check_bounds,
550
      void *out)
551
0
{
552
0
    uint32_t pixel, *ret = out;
553
554
0
    if (check_bounds &&
555
0
  (x < 0 || x >= image->width || y < 0 || y >= image->height))
556
0
    {
557
0
  *ret = 0;
558
0
  return;
559
0
    }
560
561
0
    pixel = image->fetch_pixel_32 (image, x, y);
562
563
0
    if (image->common.alpha_map)
564
0
    {
565
0
  uint32_t pixel_a;
566
567
0
  x -= image->common.alpha_origin_x;
568
0
  y -= image->common.alpha_origin_y;
569
570
0
  if (x < 0 || x >= image->common.alpha_map->width ||
571
0
      y < 0 || y >= image->common.alpha_map->height)
572
0
  {
573
0
      pixel_a = 0;
574
0
  }
575
0
  else
576
0
  {
577
0
      pixel_a = image->common.alpha_map->fetch_pixel_32 (
578
0
    image->common.alpha_map, x, y);
579
580
0
      pixel_a = ALPHA_8 (pixel_a);
581
0
  }
582
583
0
  pixel &= 0x00ffffff;
584
0
  pixel |= (pixel_a << 24);
585
0
    }
586
587
0
    *ret = pixel;
588
0
}
589
590
static force_inline void
591
fetch_pixel_general_float (bits_image_t *image,
592
      int x, int y, pixman_bool_t check_bounds,
593
      void *out)
594
0
{
595
0
    argb_t *ret = out;
596
597
0
    if (check_bounds &&
598
0
  (x < 0 || x >= image->width || y < 0 || y >= image->height))
599
0
    {
600
0
  ret->a = ret->r = ret->g = ret->b = 0;
601
0
  return;
602
0
    }
603
604
0
    *ret = image->fetch_pixel_float (image, x, y);
605
606
0
    if (image->common.alpha_map)
607
0
    {
608
0
  x -= image->common.alpha_origin_x;
609
0
  y -= image->common.alpha_origin_y;
610
611
0
  if (x < 0 || x >= image->common.alpha_map->width ||
612
0
      y < 0 || y >= image->common.alpha_map->height)
613
0
  {
614
0
      ret->a = 0.f;
615
0
  }
616
0
  else
617
0
  {
618
0
      argb_t alpha;
619
620
0
      alpha = image->common.alpha_map->fetch_pixel_float (
621
0
        image->common.alpha_map, x, y);
622
623
0
      ret->a = alpha.a;
624
0
  }
625
0
    }
626
0
}
627
628
static uint32_t *
629
__bits_image_fetch_general (pixman_iter_t  *iter,
630
          pixman_bool_t wide,
631
          const uint32_t *mask)
632
0
{
633
0
    pixman_image_t *image  = iter->image;
634
0
    int             offset = iter->x;
635
0
    int             line   = iter->y++;
636
0
    int             width  = iter->width;
637
0
    uint32_t *      buffer = iter->buffer;
638
0
    get_pixel_t     get_pixel =
639
0
  wide ? fetch_pixel_general_float : fetch_pixel_general_32;
640
641
0
    const uint32_t wide_zero[4] = {0};
642
0
    pixman_fixed_t x, y, w;
643
0
    pixman_fixed_t ux, uy, uw;
644
0
    pixman_vector_t v;
645
0
    int i;
646
647
    /* reference point is the center of the pixel */
648
0
    v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
649
0
    v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
650
0
    v.vector[2] = pixman_fixed_1;
651
652
0
    if (image->common.transform)
653
0
    {
654
0
  if (!pixman_transform_point_3d (image->common.transform, &v))
655
0
      return buffer;
656
657
0
  ux = image->common.transform->matrix[0][0];
658
0
  uy = image->common.transform->matrix[1][0];
659
0
  uw = image->common.transform->matrix[2][0];
660
0
    }
661
0
    else
662
0
    {
663
0
  ux = pixman_fixed_1;
664
0
  uy = 0;
665
0
  uw = 0;
666
0
    }
667
668
0
    x = v.vector[0];
669
0
    y = v.vector[1];
670
0
    w = v.vector[2];
671
672
0
    for (i = 0; i < width; ++i)
673
0
    {
674
0
  pixman_fixed_t x0, y0;
675
676
0
  if (!mask || (!wide && mask[i]) ||
677
0
      (wide && memcmp(&mask[4 * i], wide_zero, 16) != 0))
678
0
  {
679
0
      if (w != 0)
680
0
      {
681
0
    x0 = ((uint64_t)x << 16) / w;
682
0
    y0 = ((uint64_t)y << 16) / w;
683
0
      }
684
0
      else
685
0
      {
686
0
    x0 = 0;
687
0
    y0 = 0;
688
0
      }
689
690
0
      bits_image_fetch_pixel_filtered (
691
0
    &image->bits, wide, x0, y0, get_pixel, buffer);
692
0
  }
693
694
0
  x += ux;
695
0
  y += uy;
696
0
  w += uw;
697
0
  buffer += wide ? 4 : 1;
698
0
    }
699
700
0
    return iter->buffer;
701
0
}
702
703
static uint32_t *
704
bits_image_fetch_general_32 (pixman_iter_t  *iter,
705
           const uint32_t *mask)
706
0
{
707
0
    return __bits_image_fetch_general(iter, FALSE, mask);
708
0
}
709
710
static uint32_t *
711
bits_image_fetch_general_float (pixman_iter_t  *iter,
712
        const uint32_t *mask)
713
0
{
714
0
    return __bits_image_fetch_general(iter, TRUE, mask);
715
0
}
716
717
static void
718
replicate_pixel_32 (bits_image_t *   bits,
719
        int              x,
720
        int              y,
721
        int              width,
722
        uint32_t *       buffer)
723
0
{
724
0
    uint32_t color;
725
0
    uint32_t *end;
726
727
0
    color = bits->fetch_pixel_32 (bits, x, y);
728
729
0
    end = buffer + width;
730
0
    while (buffer < end)
731
0
  *(buffer++) = color;
732
0
}
733
734
static void
735
replicate_pixel_float (bits_image_t *   bits,
736
           int              x,
737
           int              y,
738
           int              width,
739
           uint32_t *       b)
740
0
{
741
0
    argb_t color;
742
0
    argb_t *buffer = (argb_t *)b;
743
0
    argb_t *end;
744
745
0
    color = bits->fetch_pixel_float (bits, x, y);
746
747
0
    end = buffer + width;
748
0
    while (buffer < end)
749
0
  *(buffer++) = color;
750
0
}
751
752
static void
753
bits_image_fetch_untransformed_repeat_none (bits_image_t *image,
754
                                            pixman_bool_t wide,
755
                                            int           x,
756
                                            int           y,
757
                                            int           width,
758
                                            uint32_t *    buffer)
759
0
{
760
0
    uint32_t w;
761
762
0
    if (y < 0 || y >= image->height)
763
0
    {
764
0
  memset (buffer, 0, width * (wide? sizeof (argb_t) : 4));
765
0
  return;
766
0
    }
767
768
0
    if (x < 0)
769
0
    {
770
0
  w = MIN (width, -x);
771
772
0
  memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4));
773
774
0
  width -= w;
775
0
  buffer += w * (wide? 4 : 1);
776
0
  x += w;
777
0
    }
778
779
0
    if (x < image->width)
780
0
    {
781
0
  w = MIN (width, image->width - x);
782
783
0
  if (wide)
784
0
      image->fetch_scanline_float (image, x, y, w, buffer, NULL);
785
0
  else
786
0
      image->fetch_scanline_32 (image, x, y, w, buffer, NULL);
787
788
0
  width -= w;
789
0
  buffer += w * (wide? 4 : 1);
790
0
  x += w;
791
0
    }
792
793
0
    memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4));
794
0
}
795
796
static void
797
bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
798
                                              pixman_bool_t wide,
799
                                              int           x,
800
                                              int           y,
801
                                              int           width,
802
                                              uint32_t *    buffer)
803
0
{
804
0
    uint32_t w;
805
806
0
    while (y < 0)
807
0
  y += image->height;
808
809
0
    while (y >= image->height)
810
0
  y -= image->height;
811
812
0
    if (image->width == 1)
813
0
    {
814
0
  if (wide)
815
0
      replicate_pixel_float (image, 0, y, width, buffer);
816
0
  else
817
0
      replicate_pixel_32 (image, 0, y, width, buffer);
818
819
0
  return;
820
0
    }
821
822
0
    while (width)
823
0
    {
824
0
  while (x < 0)
825
0
      x += image->width;
826
0
  while (x >= image->width)
827
0
      x -= image->width;
828
829
0
  w = MIN (width, image->width - x);
830
831
0
  if (wide)
832
0
      image->fetch_scanline_float (image, x, y, w, buffer, NULL);
833
0
  else
834
0
      image->fetch_scanline_32 (image, x, y, w, buffer, NULL);
835
836
0
  buffer += w * (wide? 4 : 1);
837
0
  x += w;
838
0
  width -= w;
839
0
    }
840
0
}
841
842
static uint32_t *
843
bits_image_fetch_untransformed_32 (pixman_iter_t * iter,
844
           const uint32_t *mask)
845
0
{
846
0
    pixman_image_t *image  = iter->image;
847
0
    int             x      = iter->x;
848
0
    int             y      = iter->y;
849
0
    int             width  = iter->width;
850
0
    uint32_t *      buffer = iter->buffer;
851
852
0
    if (image->common.repeat == PIXMAN_REPEAT_NONE)
853
0
    {
854
0
  bits_image_fetch_untransformed_repeat_none (
855
0
      &image->bits, FALSE, x, y, width, buffer);
856
0
    }
857
0
    else
858
0
    {
859
0
  bits_image_fetch_untransformed_repeat_normal (
860
0
      &image->bits, FALSE, x, y, width, buffer);
861
0
    }
862
863
0
    iter->y++;
864
0
    return buffer;
865
0
}
866
867
static uint32_t *
868
bits_image_fetch_untransformed_float (pixman_iter_t * iter,
869
              const uint32_t *mask)
870
0
{
871
0
    pixman_image_t *image  = iter->image;
872
0
    int             x      = iter->x;
873
0
    int             y      = iter->y;
874
0
    int             width  = iter->width;
875
0
    uint32_t *      buffer = iter->buffer;
876
877
0
    if (image->common.repeat == PIXMAN_REPEAT_NONE)
878
0
    {
879
0
  bits_image_fetch_untransformed_repeat_none (
880
0
      &image->bits, TRUE, x, y, width, buffer);
881
0
    }
882
0
    else
883
0
    {
884
0
  bits_image_fetch_untransformed_repeat_normal (
885
0
      &image->bits, TRUE, x, y, width, buffer);
886
0
    }
887
888
0
    iter->y++;
889
0
    return buffer;
890
0
}
891
892
typedef struct
893
{
894
    pixman_format_code_t  format;
895
    uint32_t      flags;
896
    pixman_iter_get_scanline_t  get_scanline_32;
897
    pixman_iter_get_scanline_t  get_scanline_float;
898
} fetcher_info_t;
899
900
static const fetcher_info_t fetcher_info[] =
901
{
902
    { PIXMAN_any,
903
      (FAST_PATH_NO_ALPHA_MAP     |
904
       FAST_PATH_ID_TRANSFORM     |
905
       FAST_PATH_NO_CONVOLUTION_FILTER    |
906
       FAST_PATH_NO_PAD_REPEAT      |
907
       FAST_PATH_NO_REFLECT_REPEAT),
908
      bits_image_fetch_untransformed_32,
909
      bits_image_fetch_untransformed_float
910
    },
911
912
    /* Affine, no alpha */
913
    { PIXMAN_any,
914
      (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_HAS_TRANSFORM | FAST_PATH_AFFINE_TRANSFORM),
915
      bits_image_fetch_affine_no_alpha_32,
916
      bits_image_fetch_affine_no_alpha_float,
917
    },
918
919
    /* General */
920
    { PIXMAN_any,
921
      0,
922
      bits_image_fetch_general_32,
923
      bits_image_fetch_general_float,
924
    },
925
926
    { PIXMAN_null },
927
};
928
929
static void
930
bits_image_property_changed (pixman_image_t *image)
931
37.0k
{
932
37.0k
    _pixman_bits_image_setup_accessors (&image->bits);
933
37.0k
}
934
935
void
936
_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
937
0
{
938
0
    pixman_format_code_t format = image->common.extended_format_code;
939
0
    uint32_t flags = image->common.flags;
940
0
    const fetcher_info_t *info;
941
942
0
    for (info = fetcher_info; info->format != PIXMAN_null; ++info)
943
0
    {
944
0
  if ((info->format == format || info->format == PIXMAN_any) &&
945
0
      (info->flags & flags) == info->flags)
946
0
  {
947
0
      if (iter->iter_flags & ITER_NARROW)
948
0
      {
949
0
    iter->get_scanline = info->get_scanline_32;
950
0
      }
951
0
      else
952
0
      {
953
0
    iter->get_scanline = info->get_scanline_float;
954
0
      }
955
0
      return;
956
0
  }
957
0
    }
958
959
    /* Just in case we somehow didn't find a scanline function */
960
0
    iter->get_scanline = _pixman_iter_get_scanline_noop;
961
0
}
962
963
static uint32_t *
964
dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
965
0
{
966
0
    pixman_image_t *image  = iter->image;
967
0
    int             x      = iter->x;
968
0
    int             y      = iter->y;
969
0
    int             width  = iter->width;
970
0
    uint32_t *      buffer = iter->buffer;
971
972
0
    image->bits.fetch_scanline_32 (&image->bits, x, y, width, buffer, mask);
973
0
    if (image->common.alpha_map)
974
0
    {
975
0
  uint32_t *alpha;
976
977
0
  if ((alpha = malloc (width * sizeof (uint32_t))))
978
0
  {
979
0
      int i;
980
981
0
      x -= image->common.alpha_origin_x;
982
0
      y -= image->common.alpha_origin_y;
983
984
0
      image->common.alpha_map->fetch_scanline_32 (
985
0
    image->common.alpha_map, x, y, width, alpha, mask);
986
987
0
      for (i = 0; i < width; ++i)
988
0
      {
989
0
    buffer[i] &= ~0xff000000;
990
0
    buffer[i] |= (alpha[i] & 0xff000000);
991
0
      }
992
993
0
      free (alpha);
994
0
  }
995
0
    }
996
997
0
    return iter->buffer;
998
0
}
999
1000
static uint32_t *
1001
dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
1002
0
{
1003
0
    bits_image_t *  image  = &iter->image->bits;
1004
0
    int             x      = iter->x;
1005
0
    int             y      = iter->y;
1006
0
    int             width  = iter->width;
1007
0
    argb_t *      buffer = (argb_t *)iter->buffer;
1008
1009
0
    image->fetch_scanline_float (
1010
0
  image, x, y, width, (uint32_t *)buffer, mask);
1011
0
    if (image->common.alpha_map)
1012
0
    {
1013
0
  argb_t *alpha;
1014
1015
0
  if ((alpha = malloc (width * sizeof (argb_t))))
1016
0
  {
1017
0
      int i;
1018
1019
0
      x -= image->common.alpha_origin_x;
1020
0
      y -= image->common.alpha_origin_y;
1021
1022
0
      image->common.alpha_map->fetch_scanline_float (
1023
0
    image->common.alpha_map, x, y, width, (uint32_t *)alpha, mask);
1024
1025
0
      for (i = 0; i < width; ++i)
1026
0
    buffer[i].a = alpha[i].a;
1027
1028
0
      free (alpha);
1029
0
  }
1030
0
    }
1031
1032
0
    return iter->buffer;
1033
0
}
1034
1035
static void
1036
dest_write_back_narrow (pixman_iter_t *iter)
1037
0
{
1038
0
    bits_image_t *  image  = &iter->image->bits;
1039
0
    int             x      = iter->x;
1040
0
    int             y      = iter->y;
1041
0
    int             width  = iter->width;
1042
0
    const uint32_t *buffer = iter->buffer;
1043
1044
0
    image->store_scanline_32 (image, x, y, width, buffer);
1045
1046
0
    if (image->common.alpha_map)
1047
0
    {
1048
0
  x -= image->common.alpha_origin_x;
1049
0
  y -= image->common.alpha_origin_y;
1050
1051
0
  image->common.alpha_map->store_scanline_32 (
1052
0
      image->common.alpha_map, x, y, width, buffer);
1053
0
    }
1054
1055
0
    iter->y++;
1056
0
}
1057
1058
static float
1059
dither_factor_blue_noise_64 (int x, int y)
1060
0
{
1061
0
    float m = dither_blue_noise_64x64[((y & 0x3f) << 6) | (x & 0x3f)];
1062
0
    return m * (1. / 4096.f) + (1. / 8192.f);
1063
0
}
1064
1065
static float
1066
dither_factor_bayer_8 (int x, int y)
1067
0
{
1068
0
    uint32_t m;
1069
1070
0
    y ^= x;
1071
1072
    /* Compute reverse(interleave(xor(x mod n, y mod n), x mod n))
1073
     * Here n = 8 and `mod n` is the bottom 3 bits.
1074
     */
1075
0
    m = ((y & 0x1) << 5) | ((x & 0x1) << 4) |
1076
0
  ((y & 0x2) << 2) | ((x & 0x2) << 1) |
1077
0
  ((y & 0x4) >> 1) | ((x & 0x4) >> 2);
1078
1079
    /* m is in range [0, 63].  We scale it to [0, 63.0f/64.0f], then
1080
     * shift it to to [1.0f/128.0f, 127.0f/128.0f] so that 0 < d < 1.
1081
     * This ensures exact values are not changed by dithering.
1082
     */
1083
0
    return (float)(m) * (1 / 64.0f) + (1.0f / 128.0f);
1084
0
}
1085
1086
typedef float (* dither_factor_t)(int x, int y);
1087
1088
static force_inline float
1089
dither_apply_channel (float f, float d, float s)
1090
0
{
1091
    /* float_to_unorm splits the [0, 1] segment in (1 << n_bits)
1092
     * subsections of equal length; however unorm_to_float does not
1093
     * map to the center of those sections.  In fact, pixel value u is
1094
     * mapped to:
1095
     *
1096
     *       u              u              u               1
1097
     * -------------- = ---------- + -------------- * ----------
1098
     *  2^n_bits - 1     2^n_bits     2^n_bits - 1     2^n_bits
1099
     *
1100
     * Hence if f = u / (2^n_bits - 1) is exactly representable on a
1101
     * n_bits palette, all the numbers between
1102
     *
1103
     *     u
1104
     * ----------  =  f - f * 2^n_bits = f + (0 - f) * 2^n_bits
1105
     *  2^n_bits
1106
     *
1107
     *  and
1108
     *
1109
     *    u + 1
1110
     * ---------- = f - (f - 1) * 2^n_bits = f + (1 - f) * 2^n_bits
1111
     *  2^n_bits
1112
     *
1113
     * are also mapped back to u.
1114
     *
1115
     * Hence the following calculation ensures that we add as much
1116
     * noise as possible without perturbing values which are exactly
1117
     * representable in the target colorspace.  Note that this corresponds to
1118
     * mixing the original color with noise with a ratio of `1 / 2^n_bits`.
1119
     */
1120
0
    return f + (d - f) * s;
1121
0
}
1122
1123
static force_inline float
1124
dither_compute_scale (int n_bits)
1125
0
{
1126
    // No dithering for wide formats
1127
0
    if (n_bits == 0 || n_bits >= 32)
1128
0
  return 0.f;
1129
1130
0
    return 1.f / (float)(1 << n_bits);
1131
0
}
1132
1133
static const uint32_t *
1134
dither_apply_ordered (pixman_iter_t *iter, dither_factor_t factor)
1135
0
{
1136
0
    bits_image_t        *image  = &iter->image->bits;
1137
0
    int                  x      = iter->x + image->dither_offset_x;
1138
0
    int                  y      = iter->y + image->dither_offset_y;
1139
0
    int                  width  = iter->width;
1140
0
    argb_t              *buffer = (argb_t *)iter->buffer;
1141
1142
0
    pixman_format_code_t format = image->format;
1143
0
    int                  a_size = PIXMAN_FORMAT_A (format);
1144
0
    int                  r_size = PIXMAN_FORMAT_R (format);
1145
0
    int                  g_size = PIXMAN_FORMAT_G (format);
1146
0
    int                  b_size = PIXMAN_FORMAT_B (format);
1147
1148
0
    float a_scale = dither_compute_scale (a_size);
1149
0
    float r_scale = dither_compute_scale (r_size);
1150
0
    float g_scale = dither_compute_scale (g_size);
1151
0
    float b_scale = dither_compute_scale (b_size);
1152
1153
0
    int   i;
1154
0
    float d;
1155
1156
0
    for (i = 0; i < width; ++i)
1157
0
    {
1158
0
  d = factor (x + i, y);
1159
1160
0
  buffer->a = dither_apply_channel (buffer->a, d, a_scale);
1161
0
  buffer->r = dither_apply_channel (buffer->r, d, r_scale);
1162
0
  buffer->g = dither_apply_channel (buffer->g, d, g_scale);
1163
0
  buffer->b = dither_apply_channel (buffer->b, d, b_scale);
1164
1165
0
  buffer++;
1166
0
    }
1167
1168
0
    return iter->buffer;
1169
0
}
1170
1171
static void
1172
dest_write_back_wide (pixman_iter_t *iter)
1173
0
{
1174
0
    bits_image_t *  image  = &iter->image->bits;
1175
0
    int             x      = iter->x;
1176
0
    int             y      = iter->y;
1177
0
    int             width  = iter->width;
1178
0
    const uint32_t *buffer = iter->buffer;
1179
1180
0
    switch (image->dither)
1181
0
    {
1182
0
    case PIXMAN_DITHER_NONE:
1183
0
  break;
1184
1185
0
    case PIXMAN_DITHER_GOOD:
1186
0
    case PIXMAN_DITHER_BEST:
1187
0
    case PIXMAN_DITHER_ORDERED_BLUE_NOISE_64:
1188
0
  buffer = dither_apply_ordered (iter, dither_factor_blue_noise_64);
1189
0
  break;
1190
1191
0
    case PIXMAN_DITHER_FAST:
1192
0
    case PIXMAN_DITHER_ORDERED_BAYER_8:
1193
0
  buffer = dither_apply_ordered (iter, dither_factor_bayer_8);
1194
0
  break;
1195
0
    }
1196
1197
0
    image->store_scanline_float (image, x, y, width, buffer);
1198
1199
0
    if (image->common.alpha_map)
1200
0
    {
1201
0
  x -= image->common.alpha_origin_x;
1202
0
  y -= image->common.alpha_origin_y;
1203
1204
0
  image->common.alpha_map->store_scanline_float (
1205
0
      image->common.alpha_map, x, y, width, buffer);
1206
0
    }
1207
1208
0
    iter->y++;
1209
0
}
1210
1211
void
1212
_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter)
1213
0
{
1214
0
    if (iter->iter_flags & ITER_NARROW)
1215
0
    {
1216
0
  if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
1217
0
      (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
1218
0
  {
1219
0
      iter->get_scanline = _pixman_iter_get_scanline_noop;
1220
0
  }
1221
0
  else
1222
0
  {
1223
0
      iter->get_scanline = dest_get_scanline_narrow;
1224
0
  }
1225
  
1226
0
  iter->write_back = dest_write_back_narrow;
1227
0
    }
1228
0
    else
1229
0
    {
1230
0
  iter->get_scanline = dest_get_scanline_wide;
1231
0
  iter->write_back = dest_write_back_wide;
1232
0
    }
1233
0
}
1234
1235
static uint32_t *
1236
create_bits (pixman_format_code_t format,
1237
             int                  width,
1238
             int                  height,
1239
             int *      rowstride_bytes,
1240
       pixman_bool_t    clear)
1241
73.6k
{
1242
73.6k
    int stride;
1243
73.6k
    size_t buf_size;
1244
73.6k
    int bpp;
1245
1246
    /* what follows is a long-winded way, avoiding any possibility of integer
1247
     * overflows, of saying:
1248
     * stride = ((width * bpp + 0x1f) >> 5) * sizeof (uint32_t);
1249
     */
1250
1251
73.6k
    bpp = PIXMAN_FORMAT_BPP (format);
1252
73.6k
    if (_pixman_multiply_overflows_int (width, bpp))
1253
0
  return NULL;
1254
1255
73.6k
    stride = width * bpp;
1256
73.6k
    if (_pixman_addition_overflows_int (stride, 0x1f))
1257
0
  return NULL;
1258
1259
73.6k
    stride += 0x1f;
1260
73.6k
    stride >>= 5;
1261
1262
73.6k
    stride *= sizeof (uint32_t);
1263
1264
73.6k
    if (_pixman_multiply_overflows_size (height, stride))
1265
0
  return NULL;
1266
1267
73.6k
    buf_size = (size_t)height * stride;
1268
1269
73.6k
    if (rowstride_bytes)
1270
73.6k
  *rowstride_bytes = stride;
1271
1272
73.6k
    if (clear)
1273
73.6k
  return calloc (1, buf_size);
1274
0
    else
1275
0
  return malloc (buf_size);
1276
73.6k
}
1277
1278
pixman_bool_t
1279
_pixman_bits_image_init (pixman_image_t *     image,
1280
                         pixman_format_code_t format,
1281
                         int                  width,
1282
                         int                  height,
1283
                         uint32_t *           bits,
1284
                         int                  rowstride,
1285
       pixman_bool_t        clear)
1286
93.2k
{
1287
93.2k
    uint32_t *free_me = NULL;
1288
1289
93.2k
    if (PIXMAN_FORMAT_BPP (format) == 128)
1290
26
  return_val_if_fail(!(rowstride % 4), FALSE);
1291
1292
93.2k
    if (!bits && width && height)
1293
73.6k
    {
1294
73.6k
  int rowstride_bytes;
1295
1296
73.6k
  free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear);
1297
1298
73.6k
  if (!bits)
1299
0
      return FALSE;
1300
1301
73.6k
  rowstride = rowstride_bytes / (int) sizeof (uint32_t);
1302
73.6k
    }
1303
1304
93.2k
    _pixman_image_init (image);
1305
1306
93.2k
    image->type = BITS;
1307
93.2k
    image->bits.format = format;
1308
93.2k
    image->bits.width = width;
1309
93.2k
    image->bits.height = height;
1310
93.2k
    image->bits.bits = bits;
1311
93.2k
    image->bits.free_me = free_me;
1312
93.2k
    image->bits.dither = PIXMAN_DITHER_NONE;
1313
93.2k
    image->bits.dither_offset_x = 0;
1314
93.2k
    image->bits.dither_offset_y = 0;
1315
93.2k
    image->bits.read_func = NULL;
1316
93.2k
    image->bits.write_func = NULL;
1317
93.2k
    image->bits.rowstride = rowstride;
1318
93.2k
    image->bits.indexed = NULL;
1319
1320
93.2k
    image->common.property_changed = bits_image_property_changed;
1321
1322
93.2k
    _pixman_image_reset_clip_region (image);
1323
1324
93.2k
    return TRUE;
1325
93.2k
}
1326
1327
static pixman_image_t *
1328
create_bits_image_internal (pixman_format_code_t format,
1329
          int                  width,
1330
          int                  height,
1331
          uint32_t *           bits,
1332
          int                  rowstride_bytes,
1333
          pixman_bool_t  clear)
1334
93.2k
{
1335
93.2k
    pixman_image_t *image;
1336
1337
    /* must be a whole number of uint32_t's
1338
     */
1339
93.2k
    return_val_if_fail (
1340
93.2k
  bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
1341
1342
93.2k
    return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL);
1343
1344
93.2k
    image = _pixman_image_allocate ();
1345
1346
93.2k
    if (!image)
1347
0
  return NULL;
1348
1349
93.2k
    if (!_pixman_bits_image_init (image, format, width, height, bits,
1350
93.2k
          rowstride_bytes / (int) sizeof (uint32_t),
1351
93.2k
          clear))
1352
2
    {
1353
2
  free (image);
1354
2
  return NULL;
1355
2
    }
1356
1357
93.2k
    return image;
1358
93.2k
}
1359
1360
/* If bits is NULL, a buffer will be allocated and initialized to 0 */
1361
PIXMAN_EXPORT pixman_image_t *
1362
pixman_image_create_bits (pixman_format_code_t format,
1363
                          int                  width,
1364
                          int                  height,
1365
                          uint32_t *           bits,
1366
                          int                  rowstride_bytes)
1367
93.2k
{
1368
93.2k
    return create_bits_image_internal (
1369
93.2k
  format, width, height, bits, rowstride_bytes, TRUE);
1370
93.2k
}
1371
1372
1373
/* If bits is NULL, a buffer will be allocated and _not_ initialized */
1374
PIXMAN_EXPORT pixman_image_t *
1375
pixman_image_create_bits_no_clear (pixman_format_code_t format,
1376
           int                  width,
1377
           int                  height,
1378
           uint32_t *           bits,
1379
           int                  rowstride_bytes)
1380
0
{
1381
0
    return create_bits_image_internal (
1382
0
  format, width, height, bits, rowstride_bytes, FALSE);
1383
0
}