Remove workaround for a bug in the 1.6 X server.
[profile/ivi/pixman.git] / pixman / pixman-image.c
1 /*
2  * Copyright © 2000 SuSE, Inc.
3  * Copyright © 2007 Red Hat, Inc.
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the name of SuSE not be used in advertising or
10  * publicity pertaining to distribution of the software without specific,
11  * written prior permission.  SuSE makes no representations about the
12  * suitability of this software for any purpose.  It is provided "as is"
13  * without express or implied warranty.
14  *
15  * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
17  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <assert.h>
31
32 #include "pixman-private.h"
33 #include "pixman-combine32.h"
34
35 pixman_bool_t
36 _pixman_init_gradient (gradient_t *                  gradient,
37                        const pixman_gradient_stop_t *stops,
38                        int                           n_stops)
39 {
40     return_val_if_fail (n_stops > 0, FALSE);
41
42     gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
43     if (!gradient->stops)
44         return FALSE;
45
46     memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
47
48     gradient->n_stops = n_stops;
49
50     gradient->stop_range = 0xffff;
51
52     return TRUE;
53 }
54
55 /*
56  * By default, just evaluate the image at 32bpp and expand.  Individual image
57  * types can plug in a better scanline getter if they want to. For example
58  * we  could produce smoother gradients by evaluating them at higher color
59  * depth, but that's a project for the future.
60  */
61 void
62 _pixman_image_get_scanline_generic_64 (pixman_image_t * image,
63                                        int              x,
64                                        int              y,
65                                        int              width,
66                                        uint32_t *       buffer,
67                                        const uint32_t * mask)
68 {
69     uint32_t *mask8 = NULL;
70
71     /* Contract the mask image, if one exists, so that the 32-bit fetch
72      * function can use it.
73      */
74     if (mask)
75     {
76         mask8 = pixman_malloc_ab (width, sizeof(uint32_t));
77         if (!mask8)
78             return;
79
80         pixman_contract (mask8, (uint64_t *)mask, width);
81     }
82
83     /* Fetch the source image into the first half of buffer. */
84     _pixman_image_get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8);
85
86     /* Expand from 32bpp to 64bpp in place. */
87     pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width);
88
89     free (mask8);
90 }
91
92 pixman_image_t *
93 _pixman_image_allocate (void)
94 {
95     pixman_image_t *image = malloc (sizeof (pixman_image_t));
96
97     if (image)
98     {
99         image_common_t *common = &image->common;
100
101         pixman_region32_init (&common->clip_region);
102
103         common->alpha_count = 0;
104         common->have_clip_region = FALSE;
105         common->clip_sources = FALSE;
106         common->transform = NULL;
107         common->repeat = PIXMAN_REPEAT_NONE;
108         common->filter = PIXMAN_FILTER_NEAREST;
109         common->filter_params = NULL;
110         common->n_filter_params = 0;
111         common->alpha_map = NULL;
112         common->component_alpha = FALSE;
113         common->ref_count = 1;
114         common->classify = NULL;
115         common->client_clip = FALSE;
116         common->destroy_func = NULL;
117         common->destroy_data = NULL;
118         common->dirty = TRUE;
119     }
120
121     return image;
122 }
123
124 source_image_class_t
125 _pixman_image_classify (pixman_image_t *image,
126                         int             x,
127                         int             y,
128                         int             width,
129                         int             height)
130 {
131     if (image->common.classify)
132         return image->common.classify (image, x, y, width, height);
133     else
134         return SOURCE_IMAGE_CLASS_UNKNOWN;
135 }
136
137 void
138 _pixman_image_get_scanline_32 (pixman_image_t *image,
139                                int             x,
140                                int             y,
141                                int             width,
142                                uint32_t *      buffer,
143                                const uint32_t *mask)
144 {
145     image->common.get_scanline_32 (image, x, y, width, buffer, mask);
146 }
147
148 /* Even thought the type of buffer is uint32_t *, the function actually expects
149  * a uint64_t *buffer.
150  */
151 void
152 _pixman_image_get_scanline_64 (pixman_image_t *image,
153                                int             x,
154                                int             y,
155                                int             width,
156                                uint32_t *      buffer,
157                                const uint32_t *unused)
158 {
159     image->common.get_scanline_64 (image, x, y, width, buffer, unused);
160 }
161
162 static void
163 image_property_changed (pixman_image_t *image)
164 {
165     image->common.dirty = TRUE;
166 }
167
168 /* Ref Counting */
169 PIXMAN_EXPORT pixman_image_t *
170 pixman_image_ref (pixman_image_t *image)
171 {
172     image->common.ref_count++;
173
174     return image;
175 }
176
177 /* returns TRUE when the image is freed */
178 PIXMAN_EXPORT pixman_bool_t
179 pixman_image_unref (pixman_image_t *image)
180 {
181     image_common_t *common = (image_common_t *)image;
182
183     common->ref_count--;
184
185     if (common->ref_count == 0)
186     {
187         if (image->common.destroy_func)
188             image->common.destroy_func (image, image->common.destroy_data);
189
190         pixman_region32_fini (&common->clip_region);
191
192         if (common->transform)
193             free (common->transform);
194
195         if (common->filter_params)
196             free (common->filter_params);
197
198         if (common->alpha_map)
199             pixman_image_unref ((pixman_image_t *)common->alpha_map);
200
201         if (image->type == LINEAR ||
202             image->type == RADIAL ||
203             image->type == CONICAL)
204         {
205             if (image->gradient.stops)
206                 free (image->gradient.stops);
207         }
208
209         if (image->type == BITS && image->bits.free_me)
210             free (image->bits.free_me);
211
212         free (image);
213
214         return TRUE;
215     }
216
217     return FALSE;
218 }
219
220 PIXMAN_EXPORT void
221 pixman_image_set_destroy_function (pixman_image_t *            image,
222                                    pixman_image_destroy_func_t func,
223                                    void *                      data)
224 {
225     image->common.destroy_func = func;
226     image->common.destroy_data = data;
227 }
228
229 PIXMAN_EXPORT void *
230 pixman_image_get_destroy_data (pixman_image_t *image)
231 {
232   return image->common.destroy_data;
233 }
234
235 void
236 _pixman_image_reset_clip_region (pixman_image_t *image)
237 {
238     image->common.have_clip_region = FALSE;
239 }
240
241 /* Executive Summary: This function is a no-op that only exists
242  * for historical reasons.
243  *
244  * There used to be a bug in the X server where it would rely on
245  * out-of-bounds accesses when it was asked to composite with a
246  * window as the source. It would create a pixman image pointing
247  * to some bogus position in memory, but then set a clip region
248  * to the position where the actual bits were.
249  *
250  * Due to a bug in old versions of pixman, where it would not clip
251  * against the image bounds when a clip region was set, this would
252  * actually work. So when the pixman bug was fixed, a workaround was
253  * added to allow certain out-of-bound accesses. This function disabled
254  * those workarounds.
255  *
256  * Since 0.21.2, pixman doesn't do these workarounds anymore, so now
257  * this function is a no-op.
258  */
259 PIXMAN_EXPORT void
260 pixman_disable_out_of_bounds_workaround (void)
261 {
262 }
263
264 static void
265 compute_image_info (pixman_image_t *image)
266 {
267     pixman_format_code_t code;
268     uint32_t flags = 0;
269
270     /* Transform */
271     if (!image->common.transform)
272     {
273         flags |= (FAST_PATH_ID_TRANSFORM        |
274                   FAST_PATH_X_UNIT_POSITIVE     |
275                   FAST_PATH_Y_UNIT_ZERO         |
276                   FAST_PATH_AFFINE_TRANSFORM);
277     }
278     else
279     {
280         flags |= FAST_PATH_HAS_TRANSFORM;
281
282         if (image->common.transform->matrix[2][0] == 0                  &&
283             image->common.transform->matrix[2][1] == 0                  &&
284             image->common.transform->matrix[2][2] == pixman_fixed_1)
285         {
286             flags |= FAST_PATH_AFFINE_TRANSFORM;
287
288             if (image->common.transform->matrix[0][1] == 0 &&
289                 image->common.transform->matrix[1][0] == 0)
290             {
291                 flags |= FAST_PATH_SCALE_TRANSFORM;
292             }
293         }
294
295         if (image->common.transform->matrix[0][0] > 0)
296             flags |= FAST_PATH_X_UNIT_POSITIVE;
297
298         if (image->common.transform->matrix[1][0] == 0)
299             flags |= FAST_PATH_Y_UNIT_ZERO;
300     }
301
302     /* Filter */
303     switch (image->common.filter)
304     {
305     case PIXMAN_FILTER_NEAREST:
306     case PIXMAN_FILTER_FAST:
307         flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
308         break;
309
310     case PIXMAN_FILTER_BILINEAR:
311     case PIXMAN_FILTER_GOOD:
312     case PIXMAN_FILTER_BEST:
313         flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
314         break;
315
316     case PIXMAN_FILTER_CONVOLUTION:
317         break;
318
319     default:
320         flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
321         break;
322     }
323
324     /* Repeat mode */
325     switch (image->common.repeat)
326     {
327     case PIXMAN_REPEAT_NONE:
328         flags |=
329             FAST_PATH_NO_REFLECT_REPEAT         |
330             FAST_PATH_NO_PAD_REPEAT             |
331             FAST_PATH_NO_NORMAL_REPEAT;
332         break;
333
334     case PIXMAN_REPEAT_REFLECT:
335         flags |=
336             FAST_PATH_NO_PAD_REPEAT             |
337             FAST_PATH_NO_NONE_REPEAT            |
338             FAST_PATH_NO_NORMAL_REPEAT;
339         break;
340
341     case PIXMAN_REPEAT_PAD:
342         flags |=
343             FAST_PATH_NO_REFLECT_REPEAT         |
344             FAST_PATH_NO_NONE_REPEAT            |
345             FAST_PATH_NO_NORMAL_REPEAT;
346         break;
347
348     default:
349         flags |=
350             FAST_PATH_NO_REFLECT_REPEAT         |
351             FAST_PATH_NO_PAD_REPEAT             |
352             FAST_PATH_NO_NONE_REPEAT;
353         break;
354     }
355
356     /* Component alpha */
357     if (image->common.component_alpha)
358         flags |= FAST_PATH_COMPONENT_ALPHA;
359     else
360         flags |= FAST_PATH_UNIFIED_ALPHA;
361
362     flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT);
363
364     /* Type specific checks */
365     switch (image->type)
366     {
367     case SOLID:
368         code = PIXMAN_solid;
369
370         if (image->solid.color.alpha == 0xffff)
371             flags |= FAST_PATH_IS_OPAQUE;
372         break;
373
374     case BITS:
375         if (image->bits.width == 1      &&
376             image->bits.height == 1     &&
377             image->common.repeat != PIXMAN_REPEAT_NONE)
378         {
379             code = PIXMAN_solid;
380         }
381         else
382         {
383             code = image->bits.format;
384         }
385
386         if (!PIXMAN_FORMAT_A (image->bits.format)                               &&
387             PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY         &&
388             PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR)
389         {
390             flags |= FAST_PATH_SAMPLES_OPAQUE;
391
392             if (image->common.repeat != PIXMAN_REPEAT_NONE)
393                 flags |= FAST_PATH_IS_OPAQUE;
394         }
395
396         if (image->bits.read_func || image->bits.write_func)
397             flags &= ~FAST_PATH_NO_ACCESSORS;
398
399         if (PIXMAN_FORMAT_IS_WIDE (image->bits.format))
400             flags &= ~FAST_PATH_NARROW_FORMAT;
401         break;
402
403     case LINEAR:
404     case RADIAL:
405         code = PIXMAN_unknown;
406
407         if (image->common.repeat != PIXMAN_REPEAT_NONE)
408         {
409             int i;
410
411             flags |= FAST_PATH_IS_OPAQUE;
412             for (i = 0; i < image->gradient.n_stops; ++i)
413             {
414                 if (image->gradient.stops[i].color.alpha != 0xffff)
415                 {
416                     flags &= ~FAST_PATH_IS_OPAQUE;
417                     break;
418                 }
419             }
420         }
421         break;
422
423     default:
424         code = PIXMAN_unknown;
425         break;
426     }
427
428     /* Alpha map */
429     if (!image->common.alpha_map)
430     {
431         flags |= FAST_PATH_NO_ALPHA_MAP;
432     }
433     else
434     {
435         if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format))
436             flags &= ~FAST_PATH_NARROW_FORMAT;
437     }
438
439     /* Both alpha maps and convolution filters can introduce
440      * non-opaqueness in otherwise opaque images. Also
441      * an image with component alpha turned on is only opaque
442      * if all channels are opaque, so we simply turn it off
443      * unconditionally for those images.
444      */
445     if (image->common.alpha_map                                 ||
446         image->common.filter == PIXMAN_FILTER_CONVOLUTION       ||
447         image->common.component_alpha)
448     {
449         flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE);
450     }
451
452     image->common.flags = flags;
453     image->common.extended_format_code = code;
454 }
455
456 void
457 _pixman_image_validate (pixman_image_t *image)
458 {
459     if (image->common.dirty)
460     {
461         compute_image_info (image);
462
463         /* It is important that property_changed is
464          * called *after* compute_image_info() because
465          * property_changed() can make use of the flags
466          * to set up accessors etc.
467          */
468         image->common.property_changed (image);
469
470         image->common.dirty = FALSE;
471     }
472
473     if (image->common.alpha_map)
474         _pixman_image_validate ((pixman_image_t *)image->common.alpha_map);
475 }
476
477 PIXMAN_EXPORT pixman_bool_t
478 pixman_image_set_clip_region32 (pixman_image_t *   image,
479                                 pixman_region32_t *region)
480 {
481     image_common_t *common = (image_common_t *)image;
482     pixman_bool_t result;
483
484     if (region)
485     {
486         if ((result = pixman_region32_copy (&common->clip_region, region)))
487             image->common.have_clip_region = TRUE;
488     }
489     else
490     {
491         _pixman_image_reset_clip_region (image);
492
493         result = TRUE;
494     }
495
496     image_property_changed (image);
497
498     return result;
499 }
500
501 PIXMAN_EXPORT pixman_bool_t
502 pixman_image_set_clip_region (pixman_image_t *   image,
503                               pixman_region16_t *region)
504 {
505     image_common_t *common = (image_common_t *)image;
506     pixman_bool_t result;
507
508     if (region)
509     {
510         if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region)))
511             image->common.have_clip_region = TRUE;
512     }
513     else
514     {
515         _pixman_image_reset_clip_region (image);
516
517         result = TRUE;
518     }
519
520     image_property_changed (image);
521
522     return result;
523 }
524
525 PIXMAN_EXPORT void
526 pixman_image_set_has_client_clip (pixman_image_t *image,
527                                   pixman_bool_t   client_clip)
528 {
529     image->common.client_clip = client_clip;
530 }
531
532 PIXMAN_EXPORT pixman_bool_t
533 pixman_image_set_transform (pixman_image_t *          image,
534                             const pixman_transform_t *transform)
535 {
536     static const pixman_transform_t id =
537     {
538         { { pixman_fixed_1, 0, 0 },
539           { 0, pixman_fixed_1, 0 },
540           { 0, 0, pixman_fixed_1 } }
541     };
542
543     image_common_t *common = (image_common_t *)image;
544     pixman_bool_t result;
545
546     if (common->transform == transform)
547         return TRUE;
548
549     if (memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
550     {
551         free (common->transform);
552         common->transform = NULL;
553         result = TRUE;
554
555         goto out;
556     }
557
558     if (common->transform == NULL)
559         common->transform = malloc (sizeof (pixman_transform_t));
560
561     if (common->transform == NULL)
562     {
563         result = FALSE;
564
565         goto out;
566     }
567
568     memcpy (common->transform, transform, sizeof(pixman_transform_t));
569
570     result = TRUE;
571
572 out:
573     image_property_changed (image);
574
575     return result;
576 }
577
578 PIXMAN_EXPORT void
579 pixman_image_set_repeat (pixman_image_t *image,
580                          pixman_repeat_t repeat)
581 {
582     image->common.repeat = repeat;
583
584     image_property_changed (image);
585 }
586
587 PIXMAN_EXPORT pixman_bool_t
588 pixman_image_set_filter (pixman_image_t *      image,
589                          pixman_filter_t       filter,
590                          const pixman_fixed_t *params,
591                          int                   n_params)
592 {
593     image_common_t *common = (image_common_t *)image;
594     pixman_fixed_t *new_params;
595
596     if (params == common->filter_params && filter == common->filter)
597         return TRUE;
598
599     new_params = NULL;
600     if (params)
601     {
602         new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
603         if (!new_params)
604             return FALSE;
605
606         memcpy (new_params,
607                 params, n_params * sizeof (pixman_fixed_t));
608     }
609
610     common->filter = filter;
611
612     if (common->filter_params)
613         free (common->filter_params);
614
615     common->filter_params = new_params;
616     common->n_filter_params = n_params;
617
618     image_property_changed (image);
619     return TRUE;
620 }
621
622 PIXMAN_EXPORT void
623 pixman_image_set_source_clipping (pixman_image_t *image,
624                                   pixman_bool_t   clip_sources)
625 {
626     image->common.clip_sources = clip_sources;
627
628     image_property_changed (image);
629 }
630
631 /* Unlike all the other property setters, this function does not
632  * copy the content of indexed. Doing this copying is simply
633  * way, way too expensive.
634  */
635 PIXMAN_EXPORT void
636 pixman_image_set_indexed (pixman_image_t *        image,
637                           const pixman_indexed_t *indexed)
638 {
639     bits_image_t *bits = (bits_image_t *)image;
640
641     bits->indexed = indexed;
642
643     image_property_changed (image);
644 }
645
646 PIXMAN_EXPORT void
647 pixman_image_set_alpha_map (pixman_image_t *image,
648                             pixman_image_t *alpha_map,
649                             int16_t         x,
650                             int16_t         y)
651 {
652     image_common_t *common = (image_common_t *)image;
653
654     return_if_fail (!alpha_map || alpha_map->type == BITS);
655
656     if (alpha_map && common->alpha_count > 0)
657     {
658         /* If this image is being used as an alpha map itself,
659          * then you can't give it an alpha map of its own.
660          */
661         return;
662     }
663
664     if (alpha_map && alpha_map->common.alpha_map)
665     {
666         /* If the image has an alpha map of its own,
667          * then it can't be used as an alpha map itself
668          */
669         return;
670     }
671
672     if (common->alpha_map != (bits_image_t *)alpha_map)
673     {
674         if (common->alpha_map)
675         {
676             common->alpha_map->common.alpha_count--;
677
678             pixman_image_unref ((pixman_image_t *)common->alpha_map);
679         }
680
681         if (alpha_map)
682         {
683             common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
684
685             common->alpha_map->common.alpha_count++;
686         }
687         else
688         {
689             common->alpha_map = NULL;
690         }
691     }
692
693     common->alpha_origin_x = x;
694     common->alpha_origin_y = y;
695
696     image_property_changed (image);
697 }
698
699 PIXMAN_EXPORT void
700 pixman_image_set_component_alpha   (pixman_image_t *image,
701                                     pixman_bool_t   component_alpha)
702 {
703     image->common.component_alpha = component_alpha;
704
705     image_property_changed (image);
706 }
707
708 PIXMAN_EXPORT pixman_bool_t
709 pixman_image_get_component_alpha   (pixman_image_t       *image)
710 {
711     return image->common.component_alpha;
712 }
713
714 PIXMAN_EXPORT void
715 pixman_image_set_accessors (pixman_image_t *           image,
716                             pixman_read_memory_func_t  read_func,
717                             pixman_write_memory_func_t write_func)
718 {
719     return_if_fail (image != NULL);
720
721     if (image->type == BITS)
722     {
723         image->bits.read_func = read_func;
724         image->bits.write_func = write_func;
725
726         image_property_changed (image);
727     }
728 }
729
730 PIXMAN_EXPORT uint32_t *
731 pixman_image_get_data (pixman_image_t *image)
732 {
733     if (image->type == BITS)
734         return image->bits.bits;
735
736     return NULL;
737 }
738
739 PIXMAN_EXPORT int
740 pixman_image_get_width (pixman_image_t *image)
741 {
742     if (image->type == BITS)
743         return image->bits.width;
744
745     return 0;
746 }
747
748 PIXMAN_EXPORT int
749 pixman_image_get_height (pixman_image_t *image)
750 {
751     if (image->type == BITS)
752         return image->bits.height;
753
754     return 0;
755 }
756
757 PIXMAN_EXPORT int
758 pixman_image_get_stride (pixman_image_t *image)
759 {
760     if (image->type == BITS)
761         return image->bits.rowstride * (int) sizeof (uint32_t);
762
763     return 0;
764 }
765
766 PIXMAN_EXPORT int
767 pixman_image_get_depth (pixman_image_t *image)
768 {
769     if (image->type == BITS)
770         return PIXMAN_FORMAT_DEPTH (image->bits.format);
771
772     return 0;
773 }
774
775 PIXMAN_EXPORT pixman_format_code_t
776 pixman_image_get_format (pixman_image_t *image)
777 {
778     if (image->type == BITS)
779         return image->bits.format;
780
781     return 0;
782 }
783
784 uint32_t
785 _pixman_image_get_solid (pixman_image_t *     image,
786                          pixman_format_code_t format)
787 {
788     uint32_t result;
789
790     _pixman_image_get_scanline_32 (image, 0, 0, 1, &result, NULL);
791
792     /* If necessary, convert RGB <--> BGR. */
793     if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB)
794     {
795         result = (((result & 0xff000000) >>  0) |
796                   ((result & 0x00ff0000) >> 16) |
797                   ((result & 0x0000ff00) >>  0) |
798                   ((result & 0x000000ff) << 16));
799     }
800
801     return result;
802 }