Subversion Repositories Kolibri OS

Rev

Rev 1891 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1891 serge 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á 
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 
31
#endif
32
#include 
33
#include 
34
#include 
35
#include "pixman-private.h"
36
#include "pixman-combine32.h"
3931 Serge 37
#include "pixman-inlines.h"
1891 serge 38
 
3931 Serge 39
static uint32_t *
40
_pixman_image_get_scanline_generic_float (pixman_iter_t * iter,
41
					  const uint32_t *mask)
1891 serge 42
{
3931 Serge 43
    pixman_iter_get_scanline_t fetch_32 = iter->data;
44
    uint32_t *buffer = iter->buffer;
1891 serge 45
 
3931 Serge 46
    fetch_32 (iter, NULL);
1891 serge 47
 
3931 Serge 48
    pixman_expand_to_float ((argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);
1891 serge 49
 
3931 Serge 50
    return iter->buffer;
1891 serge 51
}
52
 
53
/* Fetch functions */
54
 
55
static force_inline uint32_t
56
fetch_pixel_no_alpha (bits_image_t *image,
57
		      int x, int y, pixman_bool_t check_bounds)
58
{
59
    if (check_bounds &&
60
	(x < 0 || x >= image->width || y < 0 || y >= image->height))
61
    {
62
	return 0;
63
    }
64
 
65
    return image->fetch_pixel_32 (image, x, y);
66
}
67
 
68
typedef uint32_t (* get_pixel_t) (bits_image_t *image,
69
				  int x, int y, pixman_bool_t check_bounds);
70
 
71
static force_inline uint32_t
72
bits_image_fetch_pixel_nearest (bits_image_t   *image,
73
				pixman_fixed_t  x,
74
				pixman_fixed_t  y,
75
				get_pixel_t	get_pixel)
76
{
77
    int x0 = pixman_fixed_to_int (x - pixman_fixed_e);
78
    int y0 = pixman_fixed_to_int (y - pixman_fixed_e);
79
 
80
    if (image->common.repeat != PIXMAN_REPEAT_NONE)
81
    {
3931 Serge 82
	repeat (image->common.repeat, &x0, image->width);
83
	repeat (image->common.repeat, &y0, image->height);
1891 serge 84
 
85
	return get_pixel (image, x0, y0, FALSE);
86
    }
87
    else
88
    {
89
	return get_pixel (image, x0, y0, TRUE);
90
    }
91
}
92
 
93
static force_inline uint32_t
94
bits_image_fetch_pixel_bilinear (bits_image_t   *image,
95
				 pixman_fixed_t  x,
96
				 pixman_fixed_t  y,
97
				 get_pixel_t	 get_pixel)
98
{
99
    pixman_repeat_t repeat_mode = image->common.repeat;
100
    int width = image->width;
101
    int height = image->height;
102
    int x1, y1, x2, y2;
103
    uint32_t tl, tr, bl, br;
104
    int32_t distx, disty;
105
 
106
    x1 = x - pixman_fixed_1 / 2;
107
    y1 = y - pixman_fixed_1 / 2;
108
 
3931 Serge 109
    distx = pixman_fixed_to_bilinear_weight (x1);
110
    disty = pixman_fixed_to_bilinear_weight (y1);
1891 serge 111
 
112
    x1 = pixman_fixed_to_int (x1);
113
    y1 = pixman_fixed_to_int (y1);
114
    x2 = x1 + 1;
115
    y2 = y1 + 1;
116
 
117
    if (repeat_mode != PIXMAN_REPEAT_NONE)
118
    {
3931 Serge 119
	repeat (repeat_mode, &x1, width);
120
	repeat (repeat_mode, &y1, height);
121
	repeat (repeat_mode, &x2, width);
122
	repeat (repeat_mode, &y2, height);
1891 serge 123
 
124
	tl = get_pixel (image, x1, y1, FALSE);
125
	bl = get_pixel (image, x1, y2, FALSE);
126
	tr = get_pixel (image, x2, y1, FALSE);
127
	br = get_pixel (image, x2, y2, FALSE);
128
    }
129
    else
130
    {
131
	tl = get_pixel (image, x1, y1, TRUE);
132
	tr = get_pixel (image, x2, y1, TRUE);
133
	bl = get_pixel (image, x1, y2, TRUE);
134
	br = get_pixel (image, x2, y2, TRUE);
135
    }
136
 
137
    return bilinear_interpolation (tl, tr, bl, br, distx, disty);
138
}
139
 
3931 Serge 140
static uint32_t *
141
bits_image_fetch_bilinear_no_repeat_8888 (pixman_iter_t *iter,
142
					  const uint32_t *mask)
1891 serge 143
{
3931 Serge 144
 
145
    pixman_image_t * ima = iter->image;
146
    int              offset = iter->x;
147
    int              line = iter->y++;
148
    int              width = iter->width;
149
    uint32_t *       buffer = iter->buffer;
150
 
1891 serge 151
    bits_image_t *bits = &ima->bits;
152
    pixman_fixed_t x_top, x_bottom, x;
153
    pixman_fixed_t ux_top, ux_bottom, ux;
154
    pixman_vector_t v;
155
    uint32_t top_mask, bottom_mask;
156
    uint32_t *top_row;
157
    uint32_t *bottom_row;
158
    uint32_t *end;
159
    uint32_t zero[2] = { 0, 0 };
160
    uint32_t one = 1;
161
    int y, y1, y2;
162
    int disty;
163
    int mask_inc;
164
    int w;
165
 
166
    /* reference point is the center of the pixel */
167
    v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
168
    v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
169
    v.vector[2] = pixman_fixed_1;
170
 
171
    if (!pixman_transform_point_3d (bits->common.transform, &v))
3931 Serge 172
	return iter->buffer;
1891 serge 173
 
174
    ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0];
175
    x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2;
176
 
177
    y = v.vector[1] - pixman_fixed_1/2;
3931 Serge 178
    disty = pixman_fixed_to_bilinear_weight (y);
1891 serge 179
 
180
    /* Load the pointers to the first and second lines from the source
181
     * image that bilinear code must read.
182
     *
183
     * The main trick in this code is about the check if any line are
184
     * outside of the image;
185
     *
186
     * When I realize that a line (any one) is outside, I change
187
     * the pointer to a dummy area with zeros. Once I change this, I
188
     * must be sure the pointer will not change, so I set the
189
     * variables to each pointer increments inside the loop.
190
     */
191
    y1 = pixman_fixed_to_int (y);
192
    y2 = y1 + 1;
193
 
194
    if (y1 < 0 || y1 >= bits->height)
195
    {
196
	top_row = zero;
197
	x_top = 0;
198
	ux_top = 0;
199
    }
200
    else
201
    {
202
	top_row = bits->bits + y1 * bits->rowstride;
203
	x_top = x;
204
	ux_top = ux;
205
    }
206
 
207
    if (y2 < 0 || y2 >= bits->height)
208
    {
209
	bottom_row = zero;
210
	x_bottom = 0;
211
	ux_bottom = 0;
212
    }
213
    else
214
    {
215
	bottom_row = bits->bits + y2 * bits->rowstride;
216
	x_bottom = x;
217
	ux_bottom = ux;
218
    }
219
 
220
    /* Instead of checking whether the operation uses the mast in
221
     * each loop iteration, verify this only once and prepare the
222
     * variables to make the code smaller inside the loop.
223
     */
224
    if (!mask)
225
    {
226
        mask_inc = 0;
227
        mask = &one;
228
    }
229
    else
230
    {
231
        /* If have a mask, prepare the variables to check it */
232
        mask_inc = 1;
233
    }
234
 
235
    /* If both are zero, then the whole thing is zero */
236
    if (top_row == zero && bottom_row == zero)
237
    {
238
	memset (buffer, 0, width * sizeof (uint32_t));
3931 Serge 239
	return iter->buffer;
1891 serge 240
    }
241
    else if (bits->format == PIXMAN_x8r8g8b8)
242
    {
243
	if (top_row == zero)
244
	{
245
	    top_mask = 0;
246
	    bottom_mask = 0xff000000;
247
	}
248
	else if (bottom_row == zero)
249
	{
250
	    top_mask = 0xff000000;
251
	    bottom_mask = 0;
252
	}
253
	else
254
	{
255
	    top_mask = 0xff000000;
256
	    bottom_mask = 0xff000000;
257
	}
258
    }
259
    else
260
    {
261
	top_mask = 0;
262
	bottom_mask = 0;
263
    }
264
 
265
    end = buffer + width;
266
 
267
    /* Zero fill to the left of the image */
268
    while (buffer < end && x < pixman_fixed_minus_1)
269
    {
270
	*buffer++ = 0;
271
	x += ux;
272
	x_top += ux_top;
273
	x_bottom += ux_bottom;
274
	mask += mask_inc;
275
    }
276
 
277
    /* Left edge
278
     */
279
    while (buffer < end && x < 0)
280
    {
281
	uint32_t tr, br;
282
	int32_t distx;
283
 
284
	tr = top_row[pixman_fixed_to_int (x_top) + 1] | top_mask;
285
	br = bottom_row[pixman_fixed_to_int (x_bottom) + 1] | bottom_mask;
286
 
3931 Serge 287
	distx = pixman_fixed_to_bilinear_weight (x);
1891 serge 288
 
289
	*buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty);
290
 
291
	x += ux;
292
	x_top += ux_top;
293
	x_bottom += ux_bottom;
294
	mask += mask_inc;
295
    }
296
 
297
    /* Main part */
298
    w = pixman_int_to_fixed (bits->width - 1);
299
 
300
    while (buffer < end  &&  x < w)
301
    {
302
	if (*mask)
303
	{
304
	    uint32_t tl, tr, bl, br;
305
	    int32_t distx;
306
 
307
	    tl = top_row [pixman_fixed_to_int (x_top)] | top_mask;
308
	    tr = top_row [pixman_fixed_to_int (x_top) + 1] | top_mask;
309
	    bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask;
310
	    br = bottom_row [pixman_fixed_to_int (x_bottom) + 1] | bottom_mask;
311
 
3931 Serge 312
	    distx = pixman_fixed_to_bilinear_weight (x);
1891 serge 313
 
314
	    *buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty);
315
	}
316
 
317
	buffer++;
318
	x += ux;
319
	x_top += ux_top;
320
	x_bottom += ux_bottom;
321
	mask += mask_inc;
322
    }
323
 
324
    /* Right Edge */
325
    w = pixman_int_to_fixed (bits->width);
326
    while (buffer < end  &&  x < w)
327
    {
328
	if (*mask)
329
	{
330
	    uint32_t tl, bl;
331
	    int32_t distx;
332
 
333
	    tl = top_row [pixman_fixed_to_int (x_top)] | top_mask;
334
	    bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask;
335
 
3931 Serge 336
	    distx = pixman_fixed_to_bilinear_weight (x);
1891 serge 337
 
338
	    *buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty);
339
	}
340
 
341
	buffer++;
342
	x += ux;
343
	x_top += ux_top;
344
	x_bottom += ux_bottom;
345
	mask += mask_inc;
346
    }
347
 
348
    /* Zero fill to the left of the image */
349
    while (buffer < end)
350
	*buffer++ = 0;
3931 Serge 351
 
352
    return iter->buffer;
1891 serge 353
}
354
 
355
static force_inline uint32_t
356
bits_image_fetch_pixel_convolution (bits_image_t   *image,
357
				    pixman_fixed_t  x,
358
				    pixman_fixed_t  y,
359
				    get_pixel_t     get_pixel)
360
{
361
    pixman_fixed_t *params = image->common.filter_params;
362
    int x_off = (params[0] - pixman_fixed_1) >> 1;
363
    int y_off = (params[1] - pixman_fixed_1) >> 1;
364
    int32_t cwidth = pixman_fixed_to_int (params[0]);
365
    int32_t cheight = pixman_fixed_to_int (params[1]);
366
    int32_t i, j, x1, x2, y1, y2;
367
    pixman_repeat_t repeat_mode = image->common.repeat;
368
    int width = image->width;
369
    int height = image->height;
3931 Serge 370
    int srtot, sgtot, sbtot, satot;
1891 serge 371
 
372
    params += 2;
373
 
374
    x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
375
    y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
376
    x2 = x1 + cwidth;
377
    y2 = y1 + cheight;
378
 
379
    srtot = sgtot = sbtot = satot = 0;
380
 
381
    for (i = y1; i < y2; ++i)
382
    {
383
	for (j = x1; j < x2; ++j)
384
	{
385
	    int rx = j;
386
	    int ry = i;
387
 
388
	    pixman_fixed_t f = *params;
389
 
390
	    if (f)
391
	    {
392
		uint32_t pixel;
393
 
394
		if (repeat_mode != PIXMAN_REPEAT_NONE)
395
		{
3931 Serge 396
		    repeat (repeat_mode, &rx, width);
397
		    repeat (repeat_mode, &ry, height);
1891 serge 398
 
399
		    pixel = get_pixel (image, rx, ry, FALSE);
400
		}
401
		else
402
		{
403
		    pixel = get_pixel (image, rx, ry, TRUE);
404
		}
405
 
3931 Serge 406
		srtot += (int)RED_8 (pixel) * f;
407
		sgtot += (int)GREEN_8 (pixel) * f;
408
		sbtot += (int)BLUE_8 (pixel) * f;
409
		satot += (int)ALPHA_8 (pixel) * f;
1891 serge 410
	    }
411
 
412
	    params++;
413
	}
414
    }
415
 
3931 Serge 416
    satot = (satot + 0x8000) >> 16;
417
    srtot = (srtot + 0x8000) >> 16;
418
    sgtot = (sgtot + 0x8000) >> 16;
419
    sbtot = (sbtot + 0x8000) >> 16;
1891 serge 420
 
421
    satot = CLIP (satot, 0, 0xff);
422
    srtot = CLIP (srtot, 0, 0xff);
423
    sgtot = CLIP (sgtot, 0, 0xff);
424
    sbtot = CLIP (sbtot, 0, 0xff);
425
 
426
    return ((satot << 24) | (srtot << 16) | (sgtot <<  8) | (sbtot));
427
}
428
 
3931 Serge 429
static uint32_t
430
bits_image_fetch_pixel_separable_convolution (bits_image_t *image,
431
                                              pixman_fixed_t x,
432
                                              pixman_fixed_t y,
433
                                              get_pixel_t    get_pixel)
434
{
435
    pixman_fixed_t *params = image->common.filter_params;
436
    pixman_repeat_t repeat_mode = image->common.repeat;
437
    int width = image->width;
438
    int height = image->height;
439
    int cwidth = pixman_fixed_to_int (params[0]);
440
    int cheight = pixman_fixed_to_int (params[1]);
441
    int x_phase_bits = pixman_fixed_to_int (params[2]);
442
    int y_phase_bits = pixman_fixed_to_int (params[3]);
443
    int x_phase_shift = 16 - x_phase_bits;
444
    int y_phase_shift = 16 - y_phase_bits;
445
    int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1;
446
    int y_off = ((cheight << 16) - pixman_fixed_1) >> 1;
447
    pixman_fixed_t *y_params;
448
    int srtot, sgtot, sbtot, satot;
449
    int32_t x1, x2, y1, y2;
450
    int32_t px, py;
451
    int i, j;
452
 
453
    /* Round x and y to the middle of the closest phase before continuing. This
454
     * ensures that the convolution matrix is aligned right, since it was
455
     * positioned relative to a particular phase (and not relative to whatever
456
     * exact fraction we happen to get here).
457
     */
458
    x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
459
    y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
460
 
461
    px = (x & 0xffff) >> x_phase_shift;
462
    py = (y & 0xffff) >> y_phase_shift;
463
 
464
    y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight;
465
 
466
    x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
467
    y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
468
    x2 = x1 + cwidth;
469
    y2 = y1 + cheight;
470
 
471
    srtot = sgtot = sbtot = satot = 0;
472
 
473
    for (i = y1; i < y2; ++i)
474
    {
475
        pixman_fixed_48_16_t fy = *y_params++;
476
        pixman_fixed_t *x_params = params + 4 + px * cwidth;
477
 
478
        if (fy)
479
        {
480
            for (j = x1; j < x2; ++j)
481
            {
482
                pixman_fixed_t fx = *x_params++;
483
		int rx = j;
484
		int ry = i;
485
 
486
                if (fx)
487
                {
488
                    pixman_fixed_t f;
489
                    uint32_t pixel;
490
 
491
                    if (repeat_mode != PIXMAN_REPEAT_NONE)
492
                    {
493
                        repeat (repeat_mode, &rx, width);
494
                        repeat (repeat_mode, &ry, height);
495
 
496
                        pixel = get_pixel (image, rx, ry, FALSE);
497
                    }
498
                    else
499
                    {
500
                        pixel = get_pixel (image, rx, ry, TRUE);
501
		    }
502
 
503
                    f = (fy * fx + 0x8000) >> 16;
504
 
505
                    srtot += (int)RED_8 (pixel) * f;
506
                    sgtot += (int)GREEN_8 (pixel) * f;
507
                    sbtot += (int)BLUE_8 (pixel) * f;
508
                    satot += (int)ALPHA_8 (pixel) * f;
509
                }
510
            }
511
	}
512
    }
513
 
514
    satot = (satot + 0x8000) >> 16;
515
    srtot = (srtot + 0x8000) >> 16;
516
    sgtot = (sgtot + 0x8000) >> 16;
517
    sbtot = (sbtot + 0x8000) >> 16;
518
 
519
    satot = CLIP (satot, 0, 0xff);
520
    srtot = CLIP (srtot, 0, 0xff);
521
    sgtot = CLIP (sgtot, 0, 0xff);
522
    sbtot = CLIP (sbtot, 0, 0xff);
523
 
524
    return ((satot << 24) | (srtot << 16) | (sgtot <<  8) | (sbtot));
525
}
526
 
1891 serge 527
static force_inline uint32_t
528
bits_image_fetch_pixel_filtered (bits_image_t *image,
529
				 pixman_fixed_t x,
530
				 pixman_fixed_t y,
531
				 get_pixel_t    get_pixel)
532
{
533
    switch (image->common.filter)
534
    {
535
    case PIXMAN_FILTER_NEAREST:
536
    case PIXMAN_FILTER_FAST:
537
	return bits_image_fetch_pixel_nearest (image, x, y, get_pixel);
538
	break;
539
 
540
    case PIXMAN_FILTER_BILINEAR:
541
    case PIXMAN_FILTER_GOOD:
542
    case PIXMAN_FILTER_BEST:
543
	return bits_image_fetch_pixel_bilinear (image, x, y, get_pixel);
544
	break;
545
 
546
    case PIXMAN_FILTER_CONVOLUTION:
547
	return bits_image_fetch_pixel_convolution (image, x, y, get_pixel);
548
	break;
549
 
3931 Serge 550
    case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
551
        return bits_image_fetch_pixel_separable_convolution (image, x, y, get_pixel);
552
        break;
553
 
1891 serge 554
    default:
555
        break;
556
    }
557
 
558
    return 0;
559
}
560
 
3931 Serge 561
static uint32_t *
562
bits_image_fetch_affine_no_alpha (pixman_iter_t *  iter,
1891 serge 563
				  const uint32_t * mask)
564
{
3931 Serge 565
    pixman_image_t *image  = iter->image;
566
    int             offset = iter->x;
567
    int             line   = iter->y++;
568
    int             width  = iter->width;
569
    uint32_t *      buffer = iter->buffer;
570
 
1891 serge 571
    pixman_fixed_t x, y;
572
    pixman_fixed_t ux, uy;
573
    pixman_vector_t v;
574
    int i;
575
 
576
    /* reference point is the center of the pixel */
577
    v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
578
    v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
579
    v.vector[2] = pixman_fixed_1;
580
 
581
    if (image->common.transform)
582
    {
583
	if (!pixman_transform_point_3d (image->common.transform, &v))
3931 Serge 584
	    return iter->buffer;
1891 serge 585
 
586
	ux = image->common.transform->matrix[0][0];
587
	uy = image->common.transform->matrix[1][0];
588
    }
589
    else
590
    {
591
	ux = pixman_fixed_1;
592
	uy = 0;
593
    }
594
 
595
    x = v.vector[0];
596
    y = v.vector[1];
597
 
598
    for (i = 0; i < width; ++i)
599
    {
600
	if (!mask || mask[i])
601
	{
602
	    buffer[i] = bits_image_fetch_pixel_filtered (
603
		&image->bits, x, y, fetch_pixel_no_alpha);
604
	}
605
 
606
	x += ux;
607
	y += uy;
608
    }
3931 Serge 609
 
610
    return buffer;
1891 serge 611
}
612
 
613
/* General fetcher */
614
static force_inline uint32_t
615
fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds)
616
{
617
    uint32_t pixel;
618
 
619
    if (check_bounds &&
620
	(x < 0 || x >= image->width || y < 0 || y >= image->height))
621
    {
622
	return 0;
623
    }
624
 
625
    pixel = image->fetch_pixel_32 (image, x, y);
626
 
627
    if (image->common.alpha_map)
628
    {
629
	uint32_t pixel_a;
630
 
631
	x -= image->common.alpha_origin_x;
632
	y -= image->common.alpha_origin_y;
633
 
634
	if (x < 0 || x >= image->common.alpha_map->width ||
635
	    y < 0 || y >= image->common.alpha_map->height)
636
	{
637
	    pixel_a = 0;
638
	}
639
	else
640
	{
641
	    pixel_a = image->common.alpha_map->fetch_pixel_32 (
642
		image->common.alpha_map, x, y);
643
 
644
	    pixel_a = ALPHA_8 (pixel_a);
645
	}
646
 
647
	pixel &= 0x00ffffff;
648
	pixel |= (pixel_a << 24);
649
    }
650
 
651
    return pixel;
652
}
653
 
3931 Serge 654
static uint32_t *
655
bits_image_fetch_general (pixman_iter_t  *iter,
656
			  const uint32_t *mask)
1891 serge 657
{
3931 Serge 658
    pixman_image_t *image  = iter->image;
659
    int             offset = iter->x;
660
    int             line   = iter->y++;
661
    int             width  = iter->width;
662
    uint32_t *      buffer = iter->buffer;
663
 
1891 serge 664
    pixman_fixed_t x, y, w;
665
    pixman_fixed_t ux, uy, uw;
666
    pixman_vector_t v;
667
    int i;
668
 
669
    /* reference point is the center of the pixel */
670
    v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
671
    v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
672
    v.vector[2] = pixman_fixed_1;
673
 
674
    if (image->common.transform)
675
    {
676
	if (!pixman_transform_point_3d (image->common.transform, &v))
3931 Serge 677
	    return buffer;
1891 serge 678
 
679
	ux = image->common.transform->matrix[0][0];
680
	uy = image->common.transform->matrix[1][0];
681
	uw = image->common.transform->matrix[2][0];
682
    }
683
    else
684
    {
685
	ux = pixman_fixed_1;
686
	uy = 0;
687
	uw = 0;
688
    }
689
 
690
    x = v.vector[0];
691
    y = v.vector[1];
692
    w = v.vector[2];
693
 
694
    for (i = 0; i < width; ++i)
695
    {
696
	pixman_fixed_t x0, y0;
697
 
698
	if (!mask || mask[i])
699
	{
700
	    if (w != 0)
701
	    {
702
		x0 = ((pixman_fixed_48_16_t)x << 16) / w;
703
		y0 = ((pixman_fixed_48_16_t)y << 16) / w;
704
	    }
705
	    else
706
	    {
707
		x0 = 0;
708
		y0 = 0;
709
	    }
710
 
711
	    buffer[i] = bits_image_fetch_pixel_filtered (
712
		&image->bits, x0, y0, fetch_pixel_general);
713
	}
714
 
715
	x += ux;
716
	y += uy;
717
	w += uw;
718
    }
3931 Serge 719
 
720
    return buffer;
1891 serge 721
}
722
 
723
typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x);
724
 
725
static force_inline void
3931 Serge 726
bits_image_fetch_separable_convolution_affine (pixman_image_t * image,
727
					       int              offset,
728
					       int              line,
729
					       int              width,
730
					       uint32_t *       buffer,
731
					       const uint32_t * mask,
732
 
733
					       convert_pixel_t	convert_pixel,
734
					       pixman_format_code_t	format,
735
					       pixman_repeat_t	repeat_mode)
736
{
737
    bits_image_t *bits = &image->bits;
738
    pixman_fixed_t *params = image->common.filter_params;
739
    int cwidth = pixman_fixed_to_int (params[0]);
740
    int cheight = pixman_fixed_to_int (params[1]);
741
    int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1;
742
    int y_off = ((cheight << 16) - pixman_fixed_1) >> 1;
743
    int x_phase_bits = pixman_fixed_to_int (params[2]);
744
    int y_phase_bits = pixman_fixed_to_int (params[3]);
745
    int x_phase_shift = 16 - x_phase_bits;
746
    int y_phase_shift = 16 - y_phase_bits;
747
    pixman_fixed_t vx, vy;
748
    pixman_fixed_t ux, uy;
749
    pixman_vector_t v;
750
    int k;
751
 
752
    /* reference point is the center of the pixel */
753
    v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
754
    v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
755
    v.vector[2] = pixman_fixed_1;
756
 
757
    if (!pixman_transform_point_3d (image->common.transform, &v))
758
	return;
759
 
760
    ux = image->common.transform->matrix[0][0];
761
    uy = image->common.transform->matrix[1][0];
762
 
763
    vx = v.vector[0];
764
    vy = v.vector[1];
765
 
766
    for (k = 0; k < width; ++k)
767
    {
768
	pixman_fixed_t *y_params;
769
	int satot, srtot, sgtot, sbtot;
770
	pixman_fixed_t x, y;
771
	int32_t x1, x2, y1, y2;
772
	int32_t px, py;
773
	int i, j;
774
 
775
	if (mask && !mask[k])
776
	    goto next;
777
 
778
	/* Round x and y to the middle of the closest phase before continuing. This
779
	 * ensures that the convolution matrix is aligned right, since it was
780
	 * positioned relative to a particular phase (and not relative to whatever
781
	 * exact fraction we happen to get here).
782
	 */
783
	x = ((vx >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
784
	y = ((vy >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
785
 
786
	px = (x & 0xffff) >> x_phase_shift;
787
	py = (y & 0xffff) >> y_phase_shift;
788
 
789
	x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
790
	y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
791
	x2 = x1 + cwidth;
792
	y2 = y1 + cheight;
793
 
794
	satot = srtot = sgtot = sbtot = 0;
795
 
796
	y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight;
797
 
798
	for (i = y1; i < y2; ++i)
799
	{
800
	    pixman_fixed_t fy = *y_params++;
801
 
802
	    if (fy)
803
	    {
804
		pixman_fixed_t *x_params = params + 4 + px * cwidth;
805
 
806
		for (j = x1; j < x2; ++j)
807
		{
808
		    pixman_fixed_t fx = *x_params++;
809
		    int rx = j;
810
		    int ry = i;
811
 
812
		    if (fx)
813
		    {
814
			pixman_fixed_t f;
815
			uint32_t pixel, mask;
816
			uint8_t *row;
817
 
818
			mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
819
 
820
			if (repeat_mode != PIXMAN_REPEAT_NONE)
821
			{
822
			    repeat (repeat_mode, &rx, bits->width);
823
			    repeat (repeat_mode, &ry, bits->height);
824
 
825
			    row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry;
826
			    pixel = convert_pixel (row, rx) | mask;
827
			}
828
			else
829
			{
830
			    if (rx < 0 || ry < 0 || rx >= bits->width || ry >= bits->height)
831
			    {
832
				pixel = 0;
833
			    }
834
			    else
835
			    {
836
				row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry;
837
				pixel = convert_pixel (row, rx) | mask;
838
			    }
839
			}
840
 
841
			f = ((pixman_fixed_32_32_t)fx * fy + 0x8000) >> 16;
842
			srtot += (int)RED_8 (pixel) * f;
843
			sgtot += (int)GREEN_8 (pixel) * f;
844
			sbtot += (int)BLUE_8 (pixel) * f;
845
			satot += (int)ALPHA_8 (pixel) * f;
846
		    }
847
		}
848
	    }
849
	}
850
 
851
	satot = (satot + 0x8000) >> 16;
852
	srtot = (srtot + 0x8000) >> 16;
853
	sgtot = (sgtot + 0x8000) >> 16;
854
	sbtot = (sbtot + 0x8000) >> 16;
855
 
856
	satot = CLIP (satot, 0, 0xff);
857
	srtot = CLIP (srtot, 0, 0xff);
858
	sgtot = CLIP (sgtot, 0, 0xff);
859
	sbtot = CLIP (sbtot, 0, 0xff);
860
 
861
	buffer[k] = (satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot << 0);
862
 
863
    next:
864
	vx += ux;
865
	vy += uy;
866
    }
867
}
868
 
869
static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
870
 
871
static force_inline void
1891 serge 872
bits_image_fetch_bilinear_affine (pixman_image_t * image,
873
				  int              offset,
874
				  int              line,
875
				  int              width,
876
				  uint32_t *       buffer,
877
				  const uint32_t * mask,
878
 
879
				  convert_pixel_t	convert_pixel,
880
				  pixman_format_code_t	format,
881
				  pixman_repeat_t	repeat_mode)
882
{
883
    pixman_fixed_t x, y;
884
    pixman_fixed_t ux, uy;
885
    pixman_vector_t v;
886
    bits_image_t *bits = &image->bits;
887
    int i;
888
 
889
    /* reference point is the center of the pixel */
890
    v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
891
    v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
892
    v.vector[2] = pixman_fixed_1;
893
 
894
    if (!pixman_transform_point_3d (image->common.transform, &v))
895
	return;
896
 
897
    ux = image->common.transform->matrix[0][0];
898
    uy = image->common.transform->matrix[1][0];
899
 
900
    x = v.vector[0];
901
    y = v.vector[1];
902
 
903
    for (i = 0; i < width; ++i)
904
    {
905
	int x1, y1, x2, y2;
906
	uint32_t tl, tr, bl, br;
907
	int32_t distx, disty;
908
	int width = image->bits.width;
909
	int height = image->bits.height;
910
	const uint8_t *row1;
911
	const uint8_t *row2;
912
 
913
	if (mask && !mask[i])
914
	    goto next;
915
 
916
	x1 = x - pixman_fixed_1 / 2;
917
	y1 = y - pixman_fixed_1 / 2;
918
 
3931 Serge 919
	distx = pixman_fixed_to_bilinear_weight (x1);
920
	disty = pixman_fixed_to_bilinear_weight (y1);
1891 serge 921
 
922
	y1 = pixman_fixed_to_int (y1);
923
	y2 = y1 + 1;
924
	x1 = pixman_fixed_to_int (x1);
925
	x2 = x1 + 1;
926
 
927
	if (repeat_mode != PIXMAN_REPEAT_NONE)
928
	{
929
	    uint32_t mask;
930
 
931
	    mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
932
 
3931 Serge 933
	    repeat (repeat_mode, &x1, width);
934
	    repeat (repeat_mode, &y1, height);
935
	    repeat (repeat_mode, &x2, width);
936
	    repeat (repeat_mode, &y2, height);
1891 serge 937
 
938
	    row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1;
939
	    row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2;
940
 
941
	    tl = convert_pixel (row1, x1) | mask;
942
	    tr = convert_pixel (row1, x2) | mask;
943
	    bl = convert_pixel (row2, x1) | mask;
944
	    br = convert_pixel (row2, x2) | mask;
945
	}
946
	else
947
	{
948
	    uint32_t mask1, mask2;
949
	    int bpp;
950
 
951
	    /* Note: PIXMAN_FORMAT_BPP() returns an unsigned value,
952
	     * which means if you use it in expressions, those
953
	     * expressions become unsigned themselves. Since
954
	     * the variables below can be negative in some cases,
955
	     * that will lead to crashes on 64 bit architectures.
956
	     *
957
	     * So this line makes sure bpp is signed
958
	     */
959
	    bpp = PIXMAN_FORMAT_BPP (format);
960
 
961
	    if (x1 >= width || x2 < 0 || y1 >= height || y2 < 0)
962
	    {
963
		buffer[i] = 0;
964
		goto next;
965
	    }
966
 
967
	    if (y2 == 0)
968
	    {
969
		row1 = zero;
970
		mask1 = 0;
971
	    }
972
	    else
973
	    {
974
		row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1;
975
		row1 += bpp / 8 * x1;
976
 
977
		mask1 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
978
	    }
979
 
980
	    if (y1 == height - 1)
981
	    {
982
		row2 = zero;
983
		mask2 = 0;
984
	    }
985
	    else
986
	    {
987
		row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2;
988
		row2 += bpp / 8 * x1;
989
 
990
		mask2 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
991
	    }
992
 
993
	    if (x2 == 0)
994
	    {
995
		tl = 0;
996
		bl = 0;
997
	    }
998
	    else
999
	    {
1000
		tl = convert_pixel (row1, 0) | mask1;
1001
		bl = convert_pixel (row2, 0) | mask2;
1002
	    }
1003
 
1004
	    if (x1 == width - 1)
1005
	    {
1006
		tr = 0;
1007
		br = 0;
1008
	    }
1009
	    else
1010
	    {
1011
		tr = convert_pixel (row1, 1) | mask1;
1012
		br = convert_pixel (row2, 1) | mask2;
1013
	    }
1014
	}
1015
 
1016
	buffer[i] = bilinear_interpolation (
1017
	    tl, tr, bl, br, distx, disty);
1018
 
1019
    next:
1020
	x += ux;
1021
	y += uy;
1022
    }
1023
}
1024
 
3931 Serge 1025
static force_inline void
1026
bits_image_fetch_nearest_affine (pixman_image_t * image,
1027
				 int              offset,
1028
				 int              line,
1029
				 int              width,
1030
				 uint32_t *       buffer,
1031
				 const uint32_t * mask,
1032
 
1033
				 convert_pixel_t	convert_pixel,
1034
				 pixman_format_code_t	format,
1035
				 pixman_repeat_t	repeat_mode)
1036
{
1037
    pixman_fixed_t x, y;
1038
    pixman_fixed_t ux, uy;
1039
    pixman_vector_t v;
1040
    bits_image_t *bits = &image->bits;
1041
    int i;
1042
 
1043
    /* reference point is the center of the pixel */
1044
    v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
1045
    v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
1046
    v.vector[2] = pixman_fixed_1;
1047
 
1048
    if (!pixman_transform_point_3d (image->common.transform, &v))
1049
	return;
1050
 
1051
    ux = image->common.transform->matrix[0][0];
1052
    uy = image->common.transform->matrix[1][0];
1053
 
1054
    x = v.vector[0];
1055
    y = v.vector[1];
1056
 
1057
    for (i = 0; i < width; ++i)
1058
    {
1059
	int width, height, x0, y0;
1060
	const uint8_t *row;
1061
 
1062
	if (mask && !mask[i])
1063
	    goto next;
1064
 
1065
	width = image->bits.width;
1066
	height = image->bits.height;
1067
	x0 = pixman_fixed_to_int (x - pixman_fixed_e);
1068
	y0 = pixman_fixed_to_int (y - pixman_fixed_e);
1069
 
1070
	if (repeat_mode == PIXMAN_REPEAT_NONE &&
1071
	    (y0 < 0 || y0 >= height || x0 < 0 || x0 >= width))
1072
	{
1073
	    buffer[i] = 0;
1074
	}
1075
	else
1076
	{
1077
	    uint32_t mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
1078
 
1079
	    if (repeat_mode != PIXMAN_REPEAT_NONE)
1080
	    {
1081
		repeat (repeat_mode, &x0, width);
1082
		repeat (repeat_mode, &y0, height);
1083
	    }
1084
 
1085
	    row = (uint8_t *)bits->bits + bits->rowstride * 4 * y0;
1086
 
1087
	    buffer[i] = convert_pixel (row, x0) | mask;
1088
	}
1089
 
1090
    next:
1091
	x += ux;
1092
	y += uy;
1093
    }
1094
}
1095
 
1891 serge 1096
static force_inline uint32_t
1097
convert_a8r8g8b8 (const uint8_t *row, int x)
1098
{
1099
    return *(((uint32_t *)row) + x);
1100
}
1101
 
1102
static force_inline uint32_t
1103
convert_x8r8g8b8 (const uint8_t *row, int x)
1104
{
1105
    return *(((uint32_t *)row) + x);
1106
}
1107
 
1108
static force_inline uint32_t
1109
convert_a8 (const uint8_t *row, int x)
1110
{
1111
    return *(row + x) << 24;
1112
}
1113
 
1114
static force_inline uint32_t
1115
convert_r5g6b5 (const uint8_t *row, int x)
1116
{
3931 Serge 1117
    return convert_0565_to_0888 (*((uint16_t *)row + x));
1891 serge 1118
}
1119
 
3931 Serge 1120
#define MAKE_SEPARABLE_CONVOLUTION_FETCHER(name, format, repeat_mode)  \
1121
    static uint32_t *							\
1122
    bits_image_fetch_separable_convolution_affine_ ## name (pixman_iter_t   *iter, \
1123
							    const uint32_t * mask) \
1124
    {									\
1125
	bits_image_fetch_separable_convolution_affine (                 \
1126
	    iter->image,                                                \
1127
	    iter->x, iter->y++,                                         \
1128
	    iter->width,                                                \
1129
	    iter->buffer, mask,                                         \
1130
	    convert_ ## format,                                         \
1131
	    PIXMAN_ ## format,                                          \
1132
	    repeat_mode);                                               \
1133
									\
1134
	return iter->buffer;                                            \
1135
    }
1136
 
1891 serge 1137
#define MAKE_BILINEAR_FETCHER(name, format, repeat_mode)		\
3931 Serge 1138
    static uint32_t *							\
1139
    bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t   *iter,	\
1891 serge 1140
					       const uint32_t * mask)	\
1141
    {									\
3931 Serge 1142
	bits_image_fetch_bilinear_affine (iter->image,			\
1143
					  iter->x, iter->y++,		\
1144
					  iter->width,			\
1145
					  iter->buffer, mask,		\
1891 serge 1146
					  convert_ ## format,		\
1147
					  PIXMAN_ ## format,		\
1148
					  repeat_mode);			\
3931 Serge 1149
	return iter->buffer;						\
1150
    }
1891 serge 1151
 
3931 Serge 1152
#define MAKE_NEAREST_FETCHER(name, format, repeat_mode)			\
1153
    static uint32_t *							\
1154
    bits_image_fetch_nearest_affine_ ## name (pixman_iter_t   *iter,	\
1155
					      const uint32_t * mask)	\
1156
    {									\
1157
	bits_image_fetch_nearest_affine (iter->image,			\
1158
					 iter->x, iter->y++,		\
1159
					 iter->width,			\
1160
					 iter->buffer, mask,		\
1161
					 convert_ ## format,		\
1162
					 PIXMAN_ ## format,		\
1163
					 repeat_mode);			\
1164
	return iter->buffer;						\
1165
    }
1891 serge 1166
 
3931 Serge 1167
#define MAKE_FETCHERS(name, format, repeat_mode)			\
1168
    MAKE_NEAREST_FETCHER (name, format, repeat_mode)			\
1169
    MAKE_BILINEAR_FETCHER (name, format, repeat_mode)			\
1170
    MAKE_SEPARABLE_CONVOLUTION_FETCHER (name, format, repeat_mode)
1171
 
1172
MAKE_FETCHERS (pad_a8r8g8b8,     a8r8g8b8, PIXMAN_REPEAT_PAD)
1173
MAKE_FETCHERS (none_a8r8g8b8,    a8r8g8b8, PIXMAN_REPEAT_NONE)
1174
MAKE_FETCHERS (reflect_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_REFLECT)
1175
MAKE_FETCHERS (normal_a8r8g8b8,  a8r8g8b8, PIXMAN_REPEAT_NORMAL)
1176
MAKE_FETCHERS (pad_x8r8g8b8,     x8r8g8b8, PIXMAN_REPEAT_PAD)
1177
MAKE_FETCHERS (none_x8r8g8b8,    x8r8g8b8, PIXMAN_REPEAT_NONE)
1178
MAKE_FETCHERS (reflect_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_REFLECT)
1179
MAKE_FETCHERS (normal_x8r8g8b8,  x8r8g8b8, PIXMAN_REPEAT_NORMAL)
1180
MAKE_FETCHERS (pad_a8,           a8,       PIXMAN_REPEAT_PAD)
1181
MAKE_FETCHERS (none_a8,          a8,       PIXMAN_REPEAT_NONE)
1182
MAKE_FETCHERS (reflect_a8,	 a8,       PIXMAN_REPEAT_REFLECT)
1183
MAKE_FETCHERS (normal_a8,	 a8,       PIXMAN_REPEAT_NORMAL)
1184
MAKE_FETCHERS (pad_r5g6b5,       r5g6b5,   PIXMAN_REPEAT_PAD)
1185
MAKE_FETCHERS (none_r5g6b5,      r5g6b5,   PIXMAN_REPEAT_NONE)
1186
MAKE_FETCHERS (reflect_r5g6b5,   r5g6b5,   PIXMAN_REPEAT_REFLECT)
1187
MAKE_FETCHERS (normal_r5g6b5,    r5g6b5,   PIXMAN_REPEAT_NORMAL)
1188
 
1891 serge 1189
static void
3931 Serge 1190
replicate_pixel_32 (bits_image_t *   bits,
1191
		    int              x,
1192
		    int              y,
1193
		    int              width,
1194
		    uint32_t *       buffer)
1891 serge 1195
{
1196
    uint32_t color;
1197
    uint32_t *end;
1198
 
3931 Serge 1199
    color = bits->fetch_pixel_32 (bits, x, y);
1891 serge 1200
 
1201
    end = buffer + width;
1202
    while (buffer < end)
1203
	*(buffer++) = color;
1204
}
1205
 
1206
static void
3931 Serge 1207
replicate_pixel_float (bits_image_t *   bits,
1208
		       int              x,
1209
		       int              y,
1210
		       int              width,
1211
		       uint32_t *       b)
1891 serge 1212
{
3931 Serge 1213
    argb_t color;
1214
    argb_t *buffer = (argb_t *)b;
1215
    argb_t *end;
1891 serge 1216
 
3931 Serge 1217
    color = bits->fetch_pixel_float (bits, x, y);
1891 serge 1218
 
1219
    end = buffer + width;
1220
    while (buffer < end)
1221
	*(buffer++) = color;
1222
}
1223
 
1224
static void
1225
bits_image_fetch_untransformed_repeat_none (bits_image_t *image,
1226
                                            pixman_bool_t wide,
1227
                                            int           x,
1228
                                            int           y,
1229
                                            int           width,
1230
                                            uint32_t *    buffer)
1231
{
1232
    uint32_t w;
1233
 
1234
    if (y < 0 || y >= image->height)
1235
    {
3931 Serge 1236
	memset (buffer, 0, width * (wide? sizeof (argb_t) : 4));
1891 serge 1237
	return;
1238
    }
1239
 
1240
    if (x < 0)
1241
    {
1242
	w = MIN (width, -x);
1243
 
3931 Serge 1244
	memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4));
1891 serge 1245
 
1246
	width -= w;
3931 Serge 1247
	buffer += w * (wide? 4 : 1);
1891 serge 1248
	x += w;
1249
    }
1250
 
1251
    if (x < image->width)
1252
    {
1253
	w = MIN (width, image->width - x);
1254
 
1255
	if (wide)
3931 Serge 1256
	    image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL);
1891 serge 1257
	else
1258
	    image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL);
1259
 
1260
	width -= w;
3931 Serge 1261
	buffer += w * (wide? 4 : 1);
1891 serge 1262
	x += w;
1263
    }
1264
 
3931 Serge 1265
    memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4));
1891 serge 1266
}
1267
 
1268
static void
1269
bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
1270
                                              pixman_bool_t wide,
1271
                                              int           x,
1272
                                              int           y,
1273
                                              int           width,
1274
                                              uint32_t *    buffer)
1275
{
1276
    uint32_t w;
1277
 
1278
    while (y < 0)
1279
	y += image->height;
1280
 
1281
    while (y >= image->height)
1282
	y -= image->height;
1283
 
3931 Serge 1284
    if (image->width == 1)
1285
    {
1286
	if (wide)
1287
	    replicate_pixel_float (image, 0, y, width, buffer);
1288
	else
1289
	    replicate_pixel_32 (image, 0, y, width, buffer);
1290
 
1291
	return;
1292
    }
1293
 
1891 serge 1294
    while (width)
1295
    {
1296
	while (x < 0)
1297
	    x += image->width;
1298
	while (x >= image->width)
1299
	    x -= image->width;
1300
 
1301
	w = MIN (width, image->width - x);
1302
 
1303
	if (wide)
3931 Serge 1304
	    image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL);
1891 serge 1305
	else
1306
	    image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL);
1307
 
3931 Serge 1308
	buffer += w * (wide? 4 : 1);
1891 serge 1309
	x += w;
1310
	width -= w;
1311
    }
1312
}
1313
 
3931 Serge 1314
static uint32_t *
1315
bits_image_fetch_untransformed_32 (pixman_iter_t * iter,
1316
				   const uint32_t *mask)
1891 serge 1317
{
3931 Serge 1318
    pixman_image_t *image  = iter->image;
1319
    int             x      = iter->x;
1320
    int             y      = iter->y;
1321
    int             width  = iter->width;
1322
    uint32_t *      buffer = iter->buffer;
1323
 
1891 serge 1324
    if (image->common.repeat == PIXMAN_REPEAT_NONE)
1325
    {
1326
	bits_image_fetch_untransformed_repeat_none (
1327
	    &image->bits, FALSE, x, y, width, buffer);
1328
    }
1329
    else
1330
    {
1331
	bits_image_fetch_untransformed_repeat_normal (
1332
	    &image->bits, FALSE, x, y, width, buffer);
1333
    }
3931 Serge 1334
 
1335
    iter->y++;
1336
    return buffer;
1891 serge 1337
}
1338
 
3931 Serge 1339
static uint32_t *
1340
bits_image_fetch_untransformed_float (pixman_iter_t * iter,
1341
				      const uint32_t *mask)
1891 serge 1342
{
3931 Serge 1343
    pixman_image_t *image  = iter->image;
1344
    int             x      = iter->x;
1345
    int             y      = iter->y;
1346
    int             width  = iter->width;
1347
    uint32_t *      buffer = iter->buffer;
1348
 
1891 serge 1349
    if (image->common.repeat == PIXMAN_REPEAT_NONE)
1350
    {
1351
	bits_image_fetch_untransformed_repeat_none (
1352
	    &image->bits, TRUE, x, y, width, buffer);
1353
    }
1354
    else
1355
    {
1356
	bits_image_fetch_untransformed_repeat_normal (
1357
	    &image->bits, TRUE, x, y, width, buffer);
1358
    }
3931 Serge 1359
 
1360
    iter->y++;
1361
    return buffer;
1891 serge 1362
}
1363
 
1364
typedef struct
1365
{
1366
    pixman_format_code_t	format;
1367
    uint32_t			flags;
3931 Serge 1368
    pixman_iter_get_scanline_t	get_scanline_32;
1369
    pixman_iter_get_scanline_t  get_scanline_float;
1891 serge 1370
} fetcher_info_t;
1371
 
1372
static const fetcher_info_t fetcher_info[] =
1373
{
1374
    { PIXMAN_any,
1375
      (FAST_PATH_NO_ALPHA_MAP			|
1376
       FAST_PATH_ID_TRANSFORM			|
1377
       FAST_PATH_NO_CONVOLUTION_FILTER		|
1378
       FAST_PATH_NO_PAD_REPEAT			|
1379
       FAST_PATH_NO_REFLECT_REPEAT),
1380
      bits_image_fetch_untransformed_32,
3931 Serge 1381
      bits_image_fetch_untransformed_float
1891 serge 1382
    },
1383
 
1384
#define FAST_BILINEAR_FLAGS						\
1385
    (FAST_PATH_NO_ALPHA_MAP		|				\
1386
     FAST_PATH_NO_ACCESSORS		|				\
1387
     FAST_PATH_HAS_TRANSFORM		|				\
1388
     FAST_PATH_AFFINE_TRANSFORM		|				\
1389
     FAST_PATH_X_UNIT_POSITIVE		|				\
1390
     FAST_PATH_Y_UNIT_ZERO		|				\
1391
     FAST_PATH_NONE_REPEAT		|				\
1392
     FAST_PATH_BILINEAR_FILTER)
1393
 
1394
    { PIXMAN_a8r8g8b8,
1395
      FAST_BILINEAR_FLAGS,
1396
      bits_image_fetch_bilinear_no_repeat_8888,
3931 Serge 1397
      _pixman_image_get_scanline_generic_float
1891 serge 1398
    },
1399
 
1400
    { PIXMAN_x8r8g8b8,
1401
      FAST_BILINEAR_FLAGS,
1402
      bits_image_fetch_bilinear_no_repeat_8888,
3931 Serge 1403
      _pixman_image_get_scanline_generic_float
1891 serge 1404
    },
1405
 
1406
#define GENERAL_BILINEAR_FLAGS						\
1407
    (FAST_PATH_NO_ALPHA_MAP		|				\
1408
     FAST_PATH_NO_ACCESSORS		|				\
1409
     FAST_PATH_HAS_TRANSFORM		|				\
1410
     FAST_PATH_AFFINE_TRANSFORM		|				\
1411
     FAST_PATH_BILINEAR_FILTER)
1412
 
3931 Serge 1413
#define GENERAL_NEAREST_FLAGS						\
1414
    (FAST_PATH_NO_ALPHA_MAP		|				\
1415
     FAST_PATH_NO_ACCESSORS		|				\
1416
     FAST_PATH_HAS_TRANSFORM		|				\
1417
     FAST_PATH_AFFINE_TRANSFORM		|				\
1418
     FAST_PATH_NEAREST_FILTER)
1419
 
1420
#define GENERAL_SEPARABLE_CONVOLUTION_FLAGS				\
1421
    (FAST_PATH_NO_ALPHA_MAP            |				\
1422
     FAST_PATH_NO_ACCESSORS            |				\
1423
     FAST_PATH_HAS_TRANSFORM           |				\
1424
     FAST_PATH_AFFINE_TRANSFORM        |				\
1425
     FAST_PATH_SEPARABLE_CONVOLUTION_FILTER)
1426
 
1427
#define SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat)   \
1428
    { PIXMAN_ ## format,                                               \
1429
      GENERAL_SEPARABLE_CONVOLUTION_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \
1430
      bits_image_fetch_separable_convolution_affine_ ## name,          \
1431
      _pixman_image_get_scanline_generic_float			       \
1432
    },
1433
 
1891 serge 1434
#define BILINEAR_AFFINE_FAST_PATH(name, format, repeat)			\
1435
    { PIXMAN_ ## format,						\
1436
      GENERAL_BILINEAR_FLAGS | FAST_PATH_ ## repeat ## _REPEAT,		\
1437
      bits_image_fetch_bilinear_affine_ ## name,			\
3931 Serge 1438
      _pixman_image_get_scanline_generic_float				\
1891 serge 1439
    },
1440
 
3931 Serge 1441
#define NEAREST_AFFINE_FAST_PATH(name, format, repeat)			\
1442
    { PIXMAN_ ## format,						\
1443
      GENERAL_NEAREST_FLAGS | FAST_PATH_ ## repeat ## _REPEAT,		\
1444
      bits_image_fetch_nearest_affine_ ## name,				\
1445
      _pixman_image_get_scanline_generic_float				\
1446
    },
1891 serge 1447
 
3931 Serge 1448
#define AFFINE_FAST_PATHS(name, format, repeat)				\
1449
    SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat)	\
1450
    BILINEAR_AFFINE_FAST_PATH(name, format, repeat)			\
1451
    NEAREST_AFFINE_FAST_PATH(name, format, repeat)
1452
 
1453
    AFFINE_FAST_PATHS (pad_a8r8g8b8, a8r8g8b8, PAD)
1454
    AFFINE_FAST_PATHS (none_a8r8g8b8, a8r8g8b8, NONE)
1455
    AFFINE_FAST_PATHS (reflect_a8r8g8b8, a8r8g8b8, REFLECT)
1456
    AFFINE_FAST_PATHS (normal_a8r8g8b8, a8r8g8b8, NORMAL)
1457
    AFFINE_FAST_PATHS (pad_x8r8g8b8, x8r8g8b8, PAD)
1458
    AFFINE_FAST_PATHS (none_x8r8g8b8, x8r8g8b8, NONE)
1459
    AFFINE_FAST_PATHS (reflect_x8r8g8b8, x8r8g8b8, REFLECT)
1460
    AFFINE_FAST_PATHS (normal_x8r8g8b8, x8r8g8b8, NORMAL)
1461
    AFFINE_FAST_PATHS (pad_a8, a8, PAD)
1462
    AFFINE_FAST_PATHS (none_a8, a8, NONE)
1463
    AFFINE_FAST_PATHS (reflect_a8, a8, REFLECT)
1464
    AFFINE_FAST_PATHS (normal_a8, a8, NORMAL)
1465
    AFFINE_FAST_PATHS (pad_r5g6b5, r5g6b5, PAD)
1466
    AFFINE_FAST_PATHS (none_r5g6b5, r5g6b5, NONE)
1467
    AFFINE_FAST_PATHS (reflect_r5g6b5, r5g6b5, REFLECT)
1468
    AFFINE_FAST_PATHS (normal_r5g6b5, r5g6b5, NORMAL)
1469
 
1891 serge 1470
    /* Affine, no alpha */
1471
    { PIXMAN_any,
1472
      (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_HAS_TRANSFORM | FAST_PATH_AFFINE_TRANSFORM),
1473
      bits_image_fetch_affine_no_alpha,
3931 Serge 1474
      _pixman_image_get_scanline_generic_float
1891 serge 1475
    },
1476
 
1477
    /* General */
3931 Serge 1478
    { PIXMAN_any,
1479
      0,
1480
      bits_image_fetch_general,
1481
      _pixman_image_get_scanline_generic_float
1482
    },
1891 serge 1483
 
1484
    { PIXMAN_null },
1485
};
1486
 
1487
static void
1488
bits_image_property_changed (pixman_image_t *image)
1489
{
3931 Serge 1490
    _pixman_bits_image_setup_accessors (&image->bits);
1491
}
1492
 
1493
void
1494
_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
1495
{
1496
    pixman_format_code_t format = image->common.extended_format_code;
1891 serge 1497
    uint32_t flags = image->common.flags;
1498
    const fetcher_info_t *info;
1499
 
3931 Serge 1500
    for (info = fetcher_info; info->format != PIXMAN_null; ++info)
1891 serge 1501
    {
1502
	if ((info->format == format || info->format == PIXMAN_any)	&&
1503
	    (info->flags & flags) == info->flags)
1504
	{
3931 Serge 1505
	    if (iter->iter_flags & ITER_NARROW)
1506
	    {
1507
		iter->get_scanline = info->get_scanline_32;
1508
	    }
1509
	    else
1510
	    {
1511
		iter->data = info->get_scanline_32;
1512
		iter->get_scanline = info->get_scanline_float;
1513
	    }
1514
	    return;
1891 serge 1515
	}
3931 Serge 1516
    }
1891 serge 1517
 
3931 Serge 1518
    /* Just in case we somehow didn't find a scanline function */
1519
    iter->get_scanline = _pixman_iter_get_scanline_noop;
1520
}
1521
 
1522
static uint32_t *
1523
dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
1524
{
1525
    pixman_image_t *image  = iter->image;
1526
    int             x      = iter->x;
1527
    int             y      = iter->y;
1528
    int             width  = iter->width;
1529
    uint32_t *	    buffer = iter->buffer;
1530
 
1531
    image->bits.fetch_scanline_32 (image, x, y, width, buffer, mask);
1532
    if (image->common.alpha_map)
1533
    {
1534
	uint32_t *alpha;
1535
 
1536
	if ((alpha = malloc (width * sizeof (uint32_t))))
1537
	{
1538
	    int i;
1539
 
1540
	    x -= image->common.alpha_origin_x;
1541
	    y -= image->common.alpha_origin_y;
1542
 
1543
	    image->common.alpha_map->fetch_scanline_32 (
1544
		(pixman_image_t *)image->common.alpha_map,
1545
		x, y, width, alpha, mask);
1546
 
1547
	    for (i = 0; i < width; ++i)
1548
	    {
1549
		buffer[i] &= ~0xff000000;
1550
		buffer[i] |= (alpha[i] & 0xff000000);
1551
	    }
1552
 
1553
	    free (alpha);
1554
	}
1891 serge 1555
    }
3931 Serge 1556
 
1557
    return iter->buffer;
1891 serge 1558
}
1559
 
1560
static uint32_t *
3931 Serge 1561
dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
1562
{
1563
    bits_image_t *  image  = &iter->image->bits;
1564
    int             x      = iter->x;
1565
    int             y      = iter->y;
1566
    int             width  = iter->width;
1567
    argb_t *	    buffer = (argb_t *)iter->buffer;
1568
 
1569
    image->fetch_scanline_float (
1570
	(pixman_image_t *)image, x, y, width, (uint32_t *)buffer, mask);
1571
    if (image->common.alpha_map)
1572
    {
1573
	argb_t *alpha;
1574
 
1575
	if ((alpha = malloc (width * sizeof (argb_t))))
1576
	{
1577
	    int i;
1578
 
1579
	    x -= image->common.alpha_origin_x;
1580
	    y -= image->common.alpha_origin_y;
1581
 
1582
	    image->common.alpha_map->fetch_scanline_float (
1583
		(pixman_image_t *)image->common.alpha_map,
1584
		x, y, width, (uint32_t *)alpha, mask);
1585
 
1586
	    for (i = 0; i < width; ++i)
1587
		buffer[i].a = alpha[i].a;
1588
 
1589
	    free (alpha);
1590
	}
1591
    }
1592
 
1593
    return iter->buffer;
1594
}
1595
 
1596
static void
1597
dest_write_back_narrow (pixman_iter_t *iter)
1598
{
1599
    bits_image_t *  image  = &iter->image->bits;
1600
    int             x      = iter->x;
1601
    int             y      = iter->y;
1602
    int             width  = iter->width;
1603
    const uint32_t *buffer = iter->buffer;
1604
 
1605
    image->store_scanline_32 (image, x, y, width, buffer);
1606
 
1607
    if (image->common.alpha_map)
1608
    {
1609
	x -= image->common.alpha_origin_x;
1610
	y -= image->common.alpha_origin_y;
1611
 
1612
	image->common.alpha_map->store_scanline_32 (
1613
	    image->common.alpha_map, x, y, width, buffer);
1614
    }
1615
 
1616
    iter->y++;
1617
}
1618
 
1619
static void
1620
dest_write_back_wide (pixman_iter_t *iter)
1621
{
1622
    bits_image_t *  image  = &iter->image->bits;
1623
    int             x      = iter->x;
1624
    int             y      = iter->y;
1625
    int             width  = iter->width;
1626
    const uint32_t *buffer = iter->buffer;
1627
 
1628
    image->store_scanline_float (image, x, y, width, buffer);
1629
 
1630
    if (image->common.alpha_map)
1631
    {
1632
	x -= image->common.alpha_origin_x;
1633
	y -= image->common.alpha_origin_y;
1634
 
1635
	image->common.alpha_map->store_scanline_float (
1636
	    image->common.alpha_map, x, y, width, buffer);
1637
    }
1638
 
1639
    iter->y++;
1640
}
1641
 
1642
void
1643
_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter)
1644
{
1645
    if (iter->iter_flags & ITER_NARROW)
1646
    {
1647
	if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
1648
	    (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
1649
	{
1650
	    iter->get_scanline = _pixman_iter_get_scanline_noop;
1651
	}
1652
	else
1653
	{
1654
	    iter->get_scanline = dest_get_scanline_narrow;
1655
	}
1656
 
1657
	iter->write_back = dest_write_back_narrow;
1658
    }
1659
    else
1660
    {
1661
	iter->get_scanline = dest_get_scanline_wide;
1662
	iter->write_back = dest_write_back_wide;
1663
    }
1664
}
1665
 
1666
static uint32_t *
1891 serge 1667
create_bits (pixman_format_code_t format,
1668
             int                  width,
1669
             int                  height,
3931 Serge 1670
             int *		  rowstride_bytes,
1671
	     pixman_bool_t	  clear)
1891 serge 1672
{
1673
    int stride;
3931 Serge 1674
    size_t buf_size;
1891 serge 1675
    int bpp;
1676
 
1677
    /* what follows is a long-winded way, avoiding any possibility of integer
1678
     * overflows, of saying:
1679
     * stride = ((width * bpp + 0x1f) >> 5) * sizeof (uint32_t);
1680
     */
1681
 
1682
    bpp = PIXMAN_FORMAT_BPP (format);
3931 Serge 1683
    if (_pixman_multiply_overflows_int (width, bpp))
1891 serge 1684
	return NULL;
1685
 
1686
    stride = width * bpp;
3931 Serge 1687
    if (_pixman_addition_overflows_int (stride, 0x1f))
1891 serge 1688
	return NULL;
1689
 
1690
    stride += 0x1f;
1691
    stride >>= 5;
1692
 
1693
    stride *= sizeof (uint32_t);
1694
 
3931 Serge 1695
    if (_pixman_multiply_overflows_size (height, stride))
1891 serge 1696
	return NULL;
1697
 
1698
    buf_size = height * stride;
1699
 
1700
    if (rowstride_bytes)
1701
	*rowstride_bytes = stride;
1702
 
3931 Serge 1703
    if (clear)
1704
	return calloc (buf_size, 1);
1705
    else
1706
	return malloc (buf_size);
1891 serge 1707
}
1708
 
3931 Serge 1709
pixman_bool_t
1710
_pixman_bits_image_init (pixman_image_t *     image,
1711
                         pixman_format_code_t format,
1712
                         int                  width,
1713
                         int                  height,
1714
                         uint32_t *           bits,
1715
                         int                  rowstride,
1716
			 pixman_bool_t	      clear)
1891 serge 1717
{
1718
    uint32_t *free_me = NULL;
1719
 
1720
    if (!bits && width && height)
1721
    {
3931 Serge 1722
	int rowstride_bytes;
1891 serge 1723
 
3931 Serge 1724
	free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear);
1891 serge 1725
 
3931 Serge 1726
	if (!bits)
1727
	    return FALSE;
1891 serge 1728
 
3931 Serge 1729
	rowstride = rowstride_bytes / (int) sizeof (uint32_t);
1891 serge 1730
    }
1731
 
3931 Serge 1732
    _pixman_image_init (image);
1733
 
1891 serge 1734
    image->type = BITS;
1735
    image->bits.format = format;
1736
    image->bits.width = width;
1737
    image->bits.height = height;
1738
    image->bits.bits = bits;
1739
    image->bits.free_me = free_me;
1740
    image->bits.read_func = NULL;
1741
    image->bits.write_func = NULL;
3931 Serge 1742
    image->bits.rowstride = rowstride;
1891 serge 1743
    image->bits.indexed = NULL;
1744
 
1745
    image->common.property_changed = bits_image_property_changed;
1746
 
1747
    _pixman_image_reset_clip_region (image);
1748
 
3931 Serge 1749
    return TRUE;
1750
}
1751
 
1752
static pixman_image_t *
1753
create_bits_image_internal (pixman_format_code_t format,
1754
			    int                  width,
1755
			    int                  height,
1756
			    uint32_t *           bits,
1757
			    int                  rowstride_bytes,
1758
			    pixman_bool_t	 clear)
1759
{
1760
    pixman_image_t *image;
1761
 
1762
    /* must be a whole number of uint32_t's
1763
     */
1764
    return_val_if_fail (
1765
	bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
1766
 
1767
    return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL);
1768
 
1769
    image = _pixman_image_allocate ();
1770
 
1771
    if (!image)
1772
	return NULL;
1773
 
1774
    if (!_pixman_bits_image_init (image, format, width, height, bits,
1775
				  rowstride_bytes / (int) sizeof (uint32_t),
1776
				  clear))
1777
    {
1778
	free (image);
1779
	return NULL;
1780
    }
1781
 
1891 serge 1782
    return image;
1783
}
3931 Serge 1784
 
1785
/* If bits is NULL, a buffer will be allocated and initialized to 0 */
1786
PIXMAN_EXPORT pixman_image_t *
1787
pixman_image_create_bits (pixman_format_code_t format,
1788
                          int                  width,
1789
                          int                  height,
1790
                          uint32_t *           bits,
1791
                          int                  rowstride_bytes)
1792
{
1793
    return create_bits_image_internal (
1794
	format, width, height, bits, rowstride_bytes, TRUE);
1795
}
1796
 
1797
 
1798
/* If bits is NULL, a buffer will be allocated and _not_ initialized */
1799
PIXMAN_EXPORT pixman_image_t *
1800
pixman_image_create_bits_no_clear (pixman_format_code_t format,
1801
				   int                  width,
1802
				   int                  height,
1803
				   uint32_t *           bits,
1804
				   int                  rowstride_bytes)
1805
{
1806
    return create_bits_image_internal (
1807
	format, width, height, bits, rowstride_bytes, FALSE);
1808
}