Move get_scanline_32/64 to the bits part of the image struct
[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     return TRUE;
51 }
52
53 pixman_image_t *
54 _pixman_image_allocate (void)
55 {
56     pixman_image_t *image = malloc (sizeof (pixman_image_t));
57
58     if (image)
59     {
60         image_common_t *common = &image->common;
61
62         pixman_region32_init (&common->clip_region);
63
64         common->alpha_count = 0;
65         common->have_clip_region = FALSE;
66         common->clip_sources = FALSE;
67         common->transform = NULL;
68         common->repeat = PIXMAN_REPEAT_NONE;
69         common->filter = PIXMAN_FILTER_NEAREST;
70         common->filter_params = NULL;
71         common->n_filter_params = 0;
72         common->alpha_map = NULL;
73         common->component_alpha = FALSE;
74         common->ref_count = 1;
75         common->classify = NULL;
76         common->client_clip = FALSE;
77         common->destroy_func = NULL;
78         common->destroy_data = NULL;
79         common->dirty = TRUE;
80     }
81
82     return image;
83 }
84
85 source_image_class_t
86 _pixman_image_classify (pixman_image_t *image,
87                         int             x,
88                         int             y,
89                         int             width,
90                         int             height)
91 {
92     if (image->common.classify)
93         return image->common.classify (image, x, y, width, height);
94     else
95         return SOURCE_IMAGE_CLASS_UNKNOWN;
96 }
97
98 static void
99 image_property_changed (pixman_image_t *image)
100 {
101     image->common.dirty = TRUE;
102 }
103
104 /* Ref Counting */
105 PIXMAN_EXPORT pixman_image_t *
106 pixman_image_ref (pixman_image_t *image)
107 {
108     image->common.ref_count++;
109
110     return image;
111 }
112
113 /* returns TRUE when the image is freed */
114 PIXMAN_EXPORT pixman_bool_t
115 pixman_image_unref (pixman_image_t *image)
116 {
117     image_common_t *common = (image_common_t *)image;
118
119     common->ref_count--;
120
121     if (common->ref_count == 0)
122     {
123         if (image->common.destroy_func)
124             image->common.destroy_func (image, image->common.destroy_data);
125
126         pixman_region32_fini (&common->clip_region);
127
128         if (common->transform)
129             free (common->transform);
130
131         if (common->filter_params)
132             free (common->filter_params);
133
134         if (common->alpha_map)
135             pixman_image_unref ((pixman_image_t *)common->alpha_map);
136
137         if (image->type == LINEAR ||
138             image->type == RADIAL ||
139             image->type == CONICAL)
140         {
141             if (image->gradient.stops)
142                 free (image->gradient.stops);
143         }
144
145         if (image->type == BITS && image->bits.free_me)
146             free (image->bits.free_me);
147
148         free (image);
149
150         return TRUE;
151     }
152
153     return FALSE;
154 }
155
156 PIXMAN_EXPORT void
157 pixman_image_set_destroy_function (pixman_image_t *            image,
158                                    pixman_image_destroy_func_t func,
159                                    void *                      data)
160 {
161     image->common.destroy_func = func;
162     image->common.destroy_data = data;
163 }
164
165 PIXMAN_EXPORT void *
166 pixman_image_get_destroy_data (pixman_image_t *image)
167 {
168   return image->common.destroy_data;
169 }
170
171 void
172 _pixman_image_reset_clip_region (pixman_image_t *image)
173 {
174     image->common.have_clip_region = FALSE;
175 }
176
177 /* Executive Summary: This function is a no-op that only exists
178  * for historical reasons.
179  *
180  * There used to be a bug in the X server where it would rely on
181  * out-of-bounds accesses when it was asked to composite with a
182  * window as the source. It would create a pixman image pointing
183  * to some bogus position in memory, but then set a clip region
184  * to the position where the actual bits were.
185  *
186  * Due to a bug in old versions of pixman, where it would not clip
187  * against the image bounds when a clip region was set, this would
188  * actually work. So when the pixman bug was fixed, a workaround was
189  * added to allow certain out-of-bound accesses. This function disabled
190  * those workarounds.
191  *
192  * Since 0.21.2, pixman doesn't do these workarounds anymore, so now
193  * this function is a no-op.
194  */
195 PIXMAN_EXPORT void
196 pixman_disable_out_of_bounds_workaround (void)
197 {
198 }
199
200 static void
201 compute_image_info (pixman_image_t *image)
202 {
203     pixman_format_code_t code;
204     uint32_t flags = 0;
205
206     /* Transform */
207     if (!image->common.transform)
208     {
209         flags |= (FAST_PATH_ID_TRANSFORM        |
210                   FAST_PATH_X_UNIT_POSITIVE     |
211                   FAST_PATH_Y_UNIT_ZERO         |
212                   FAST_PATH_AFFINE_TRANSFORM);
213     }
214     else
215     {
216         flags |= FAST_PATH_HAS_TRANSFORM;
217
218         if (image->common.transform->matrix[2][0] == 0                  &&
219             image->common.transform->matrix[2][1] == 0                  &&
220             image->common.transform->matrix[2][2] == pixman_fixed_1)
221         {
222             flags |= FAST_PATH_AFFINE_TRANSFORM;
223
224             if (image->common.transform->matrix[0][1] == 0 &&
225                 image->common.transform->matrix[1][0] == 0)
226             {
227                 flags |= FAST_PATH_SCALE_TRANSFORM;
228             }
229         }
230
231         if (image->common.transform->matrix[0][0] > 0)
232             flags |= FAST_PATH_X_UNIT_POSITIVE;
233
234         if (image->common.transform->matrix[1][0] == 0)
235             flags |= FAST_PATH_Y_UNIT_ZERO;
236     }
237
238     /* Filter */
239     switch (image->common.filter)
240     {
241     case PIXMAN_FILTER_NEAREST:
242     case PIXMAN_FILTER_FAST:
243         flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
244         break;
245
246     case PIXMAN_FILTER_BILINEAR:
247     case PIXMAN_FILTER_GOOD:
248     case PIXMAN_FILTER_BEST:
249         flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
250         break;
251
252     case PIXMAN_FILTER_CONVOLUTION:
253         break;
254
255     default:
256         flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
257         break;
258     }
259
260     /* Repeat mode */
261     switch (image->common.repeat)
262     {
263     case PIXMAN_REPEAT_NONE:
264         flags |=
265             FAST_PATH_NO_REFLECT_REPEAT         |
266             FAST_PATH_NO_PAD_REPEAT             |
267             FAST_PATH_NO_NORMAL_REPEAT;
268         break;
269
270     case PIXMAN_REPEAT_REFLECT:
271         flags |=
272             FAST_PATH_NO_PAD_REPEAT             |
273             FAST_PATH_NO_NONE_REPEAT            |
274             FAST_PATH_NO_NORMAL_REPEAT;
275         break;
276
277     case PIXMAN_REPEAT_PAD:
278         flags |=
279             FAST_PATH_NO_REFLECT_REPEAT         |
280             FAST_PATH_NO_NONE_REPEAT            |
281             FAST_PATH_NO_NORMAL_REPEAT;
282         break;
283
284     default:
285         flags |=
286             FAST_PATH_NO_REFLECT_REPEAT         |
287             FAST_PATH_NO_PAD_REPEAT             |
288             FAST_PATH_NO_NONE_REPEAT;
289         break;
290     }
291
292     /* Component alpha */
293     if (image->common.component_alpha)
294         flags |= FAST_PATH_COMPONENT_ALPHA;
295     else
296         flags |= FAST_PATH_UNIFIED_ALPHA;
297
298     flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT);
299
300     /* Type specific checks */
301     switch (image->type)
302     {
303     case SOLID:
304         code = PIXMAN_solid;
305
306         if (image->solid.color.alpha == 0xffff)
307             flags |= FAST_PATH_IS_OPAQUE;
308         break;
309
310     case BITS:
311         if (image->bits.width == 1      &&
312             image->bits.height == 1     &&
313             image->common.repeat != PIXMAN_REPEAT_NONE)
314         {
315             code = PIXMAN_solid;
316         }
317         else
318         {
319             code = image->bits.format;
320         }
321
322         if (!PIXMAN_FORMAT_A (image->bits.format)                               &&
323             PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY         &&
324             PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR)
325         {
326             flags |= FAST_PATH_SAMPLES_OPAQUE;
327
328             if (image->common.repeat != PIXMAN_REPEAT_NONE)
329                 flags |= FAST_PATH_IS_OPAQUE;
330         }
331
332         if (image->bits.read_func || image->bits.write_func)
333             flags &= ~FAST_PATH_NO_ACCESSORS;
334
335         if (PIXMAN_FORMAT_IS_WIDE (image->bits.format))
336             flags &= ~FAST_PATH_NARROW_FORMAT;
337         break;
338
339     case RADIAL:
340         code = PIXMAN_unknown;
341
342         /*
343          * As explained in pixman-radial-gradient.c, every point of
344          * the plane has a valid associated radius (and thus will be
345          * colored) if and only if a is negative (i.e. one of the two
346          * circles contains the other one).
347          */
348
349         if (image->radial.a >= 0)
350             break;
351
352         /* Fall through */
353
354     case CONICAL:
355     case LINEAR:
356         code = PIXMAN_unknown;
357
358         if (image->common.repeat != PIXMAN_REPEAT_NONE)
359         {
360             int i;
361
362             flags |= FAST_PATH_IS_OPAQUE;
363             for (i = 0; i < image->gradient.n_stops; ++i)
364             {
365                 if (image->gradient.stops[i].color.alpha != 0xffff)
366                 {
367                     flags &= ~FAST_PATH_IS_OPAQUE;
368                     break;
369                 }
370             }
371         }
372         break;
373
374     default:
375         code = PIXMAN_unknown;
376         break;
377     }
378
379     /* Alpha map */
380     if (!image->common.alpha_map)
381     {
382         flags |= FAST_PATH_NO_ALPHA_MAP;
383     }
384     else
385     {
386         if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format))
387             flags &= ~FAST_PATH_NARROW_FORMAT;
388     }
389
390     /* Both alpha maps and convolution filters can introduce
391      * non-opaqueness in otherwise opaque images. Also
392      * an image with component alpha turned on is only opaque
393      * if all channels are opaque, so we simply turn it off
394      * unconditionally for those images.
395      */
396     if (image->common.alpha_map                                 ||
397         image->common.filter == PIXMAN_FILTER_CONVOLUTION       ||
398         image->common.component_alpha)
399     {
400         flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE);
401     }
402
403     image->common.flags = flags;
404     image->common.extended_format_code = code;
405 }
406
407 void
408 _pixman_image_validate (pixman_image_t *image)
409 {
410     if (image->common.dirty)
411     {
412         compute_image_info (image);
413
414         /* It is important that property_changed is
415          * called *after* compute_image_info() because
416          * property_changed() can make use of the flags
417          * to set up accessors etc.
418          */
419         image->common.property_changed (image);
420
421         image->common.dirty = FALSE;
422     }
423
424     if (image->common.alpha_map)
425         _pixman_image_validate ((pixman_image_t *)image->common.alpha_map);
426 }
427
428 PIXMAN_EXPORT pixman_bool_t
429 pixman_image_set_clip_region32 (pixman_image_t *   image,
430                                 pixman_region32_t *region)
431 {
432     image_common_t *common = (image_common_t *)image;
433     pixman_bool_t result;
434
435     if (region)
436     {
437         if ((result = pixman_region32_copy (&common->clip_region, region)))
438             image->common.have_clip_region = TRUE;
439     }
440     else
441     {
442         _pixman_image_reset_clip_region (image);
443
444         result = TRUE;
445     }
446
447     image_property_changed (image);
448
449     return result;
450 }
451
452 PIXMAN_EXPORT pixman_bool_t
453 pixman_image_set_clip_region (pixman_image_t *   image,
454                               pixman_region16_t *region)
455 {
456     image_common_t *common = (image_common_t *)image;
457     pixman_bool_t result;
458
459     if (region)
460     {
461         if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region)))
462             image->common.have_clip_region = TRUE;
463     }
464     else
465     {
466         _pixman_image_reset_clip_region (image);
467
468         result = TRUE;
469     }
470
471     image_property_changed (image);
472
473     return result;
474 }
475
476 PIXMAN_EXPORT void
477 pixman_image_set_has_client_clip (pixman_image_t *image,
478                                   pixman_bool_t   client_clip)
479 {
480     image->common.client_clip = client_clip;
481 }
482
483 PIXMAN_EXPORT pixman_bool_t
484 pixman_image_set_transform (pixman_image_t *          image,
485                             const pixman_transform_t *transform)
486 {
487     static const pixman_transform_t id =
488     {
489         { { pixman_fixed_1, 0, 0 },
490           { 0, pixman_fixed_1, 0 },
491           { 0, 0, pixman_fixed_1 } }
492     };
493
494     image_common_t *common = (image_common_t *)image;
495     pixman_bool_t result;
496
497     if (common->transform == transform)
498         return TRUE;
499
500     if (memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
501     {
502         free (common->transform);
503         common->transform = NULL;
504         result = TRUE;
505
506         goto out;
507     }
508
509     if (common->transform == NULL)
510         common->transform = malloc (sizeof (pixman_transform_t));
511
512     if (common->transform == NULL)
513     {
514         result = FALSE;
515
516         goto out;
517     }
518
519     memcpy (common->transform, transform, sizeof(pixman_transform_t));
520
521     result = TRUE;
522
523 out:
524     image_property_changed (image);
525
526     return result;
527 }
528
529 PIXMAN_EXPORT void
530 pixman_image_set_repeat (pixman_image_t *image,
531                          pixman_repeat_t repeat)
532 {
533     image->common.repeat = repeat;
534
535     image_property_changed (image);
536 }
537
538 PIXMAN_EXPORT pixman_bool_t
539 pixman_image_set_filter (pixman_image_t *      image,
540                          pixman_filter_t       filter,
541                          const pixman_fixed_t *params,
542                          int                   n_params)
543 {
544     image_common_t *common = (image_common_t *)image;
545     pixman_fixed_t *new_params;
546
547     if (params == common->filter_params && filter == common->filter)
548         return TRUE;
549
550     new_params = NULL;
551     if (params)
552     {
553         new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
554         if (!new_params)
555             return FALSE;
556
557         memcpy (new_params,
558                 params, n_params * sizeof (pixman_fixed_t));
559     }
560
561     common->filter = filter;
562
563     if (common->filter_params)
564         free (common->filter_params);
565
566     common->filter_params = new_params;
567     common->n_filter_params = n_params;
568
569     image_property_changed (image);
570     return TRUE;
571 }
572
573 PIXMAN_EXPORT void
574 pixman_image_set_source_clipping (pixman_image_t *image,
575                                   pixman_bool_t   clip_sources)
576 {
577     image->common.clip_sources = clip_sources;
578
579     image_property_changed (image);
580 }
581
582 /* Unlike all the other property setters, this function does not
583  * copy the content of indexed. Doing this copying is simply
584  * way, way too expensive.
585  */
586 PIXMAN_EXPORT void
587 pixman_image_set_indexed (pixman_image_t *        image,
588                           const pixman_indexed_t *indexed)
589 {
590     bits_image_t *bits = (bits_image_t *)image;
591
592     bits->indexed = indexed;
593
594     image_property_changed (image);
595 }
596
597 PIXMAN_EXPORT void
598 pixman_image_set_alpha_map (pixman_image_t *image,
599                             pixman_image_t *alpha_map,
600                             int16_t         x,
601                             int16_t         y)
602 {
603     image_common_t *common = (image_common_t *)image;
604
605     return_if_fail (!alpha_map || alpha_map->type == BITS);
606
607     if (alpha_map && common->alpha_count > 0)
608     {
609         /* If this image is being used as an alpha map itself,
610          * then you can't give it an alpha map of its own.
611          */
612         return;
613     }
614
615     if (alpha_map && alpha_map->common.alpha_map)
616     {
617         /* If the image has an alpha map of its own,
618          * then it can't be used as an alpha map itself
619          */
620         return;
621     }
622
623     if (common->alpha_map != (bits_image_t *)alpha_map)
624     {
625         if (common->alpha_map)
626         {
627             common->alpha_map->common.alpha_count--;
628
629             pixman_image_unref ((pixman_image_t *)common->alpha_map);
630         }
631
632         if (alpha_map)
633         {
634             common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
635
636             common->alpha_map->common.alpha_count++;
637         }
638         else
639         {
640             common->alpha_map = NULL;
641         }
642     }
643
644     common->alpha_origin_x = x;
645     common->alpha_origin_y = y;
646
647     image_property_changed (image);
648 }
649
650 PIXMAN_EXPORT void
651 pixman_image_set_component_alpha   (pixman_image_t *image,
652                                     pixman_bool_t   component_alpha)
653 {
654     image->common.component_alpha = component_alpha;
655
656     image_property_changed (image);
657 }
658
659 PIXMAN_EXPORT pixman_bool_t
660 pixman_image_get_component_alpha   (pixman_image_t       *image)
661 {
662     return image->common.component_alpha;
663 }
664
665 PIXMAN_EXPORT void
666 pixman_image_set_accessors (pixman_image_t *           image,
667                             pixman_read_memory_func_t  read_func,
668                             pixman_write_memory_func_t write_func)
669 {
670     return_if_fail (image != NULL);
671
672     if (image->type == BITS)
673     {
674         image->bits.read_func = read_func;
675         image->bits.write_func = write_func;
676
677         image_property_changed (image);
678     }
679 }
680
681 PIXMAN_EXPORT uint32_t *
682 pixman_image_get_data (pixman_image_t *image)
683 {
684     if (image->type == BITS)
685         return image->bits.bits;
686
687     return NULL;
688 }
689
690 PIXMAN_EXPORT int
691 pixman_image_get_width (pixman_image_t *image)
692 {
693     if (image->type == BITS)
694         return image->bits.width;
695
696     return 0;
697 }
698
699 PIXMAN_EXPORT int
700 pixman_image_get_height (pixman_image_t *image)
701 {
702     if (image->type == BITS)
703         return image->bits.height;
704
705     return 0;
706 }
707
708 PIXMAN_EXPORT int
709 pixman_image_get_stride (pixman_image_t *image)
710 {
711     if (image->type == BITS)
712         return image->bits.rowstride * (int) sizeof (uint32_t);
713
714     return 0;
715 }
716
717 PIXMAN_EXPORT int
718 pixman_image_get_depth (pixman_image_t *image)
719 {
720     if (image->type == BITS)
721         return PIXMAN_FORMAT_DEPTH (image->bits.format);
722
723     return 0;
724 }
725
726 PIXMAN_EXPORT pixman_format_code_t
727 pixman_image_get_format (pixman_image_t *image)
728 {
729     if (image->type == BITS)
730         return image->bits.format;
731
732     return 0;
733 }
734
735 uint32_t
736 _pixman_image_get_solid (pixman_implementation_t *imp,
737                          pixman_image_t *         image,
738                          pixman_format_code_t     format)
739 {
740     uint32_t result;
741     pixman_iter_t iter;
742
743     _pixman_implementation_src_iter_init (
744         imp, &iter, image, 0, 0, 1, 1,
745         (uint8_t *)&result, ITER_NARROW);
746
747     result = *iter.get_scanline (&iter, NULL);
748
749     /* If necessary, convert RGB <--> BGR. */
750     if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB)
751     {
752         result = (((result & 0xff000000) >>  0) |
753                   ((result & 0x00ff0000) >> 16) |
754                   ((result & 0x0000ff00) >>  0) |
755                   ((result & 0x000000ff) << 16));
756     }
757
758     return result;
759 }