Add stubs for property_changed virtual functions
[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
31 #include "pixman-private.h"
32
33 #define Alpha(x) ((x) >> 24)
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     gradient->color_table = NULL;
52     gradient->color_table_size = 0;
53     gradient->common.class = SOURCE_IMAGE_CLASS_UNKNOWN;
54
55     return TRUE;
56 }
57
58 pixman_image_t *
59 _pixman_image_allocate (void)
60 {
61     pixman_image_t *image = malloc (sizeof (pixman_image_t));
62
63     if (image)
64     {
65         image_common_t *common = &image->common;
66
67         pixman_region32_init (&common->full_region);
68         pixman_region32_init (&common->clip_region);
69         common->src_clip = &common->full_region;
70         common->has_client_clip = FALSE;
71         common->transform = NULL;
72         common->repeat = PIXMAN_REPEAT_NONE;
73         common->filter = PIXMAN_FILTER_NEAREST;
74         common->filter_params = NULL;
75         common->n_filter_params = 0;
76         common->alpha_map = NULL;
77         common->component_alpha = FALSE;
78         common->ref_count = 1;
79         common->read_func = NULL;
80         common->write_func = NULL;
81         common->classify = NULL;
82     }
83
84     return image;
85 }
86
87 source_pict_class_t
88 _pixman_image_classify (pixman_image_t *image,
89                         int             x,
90                         int             y,
91                         int             width,
92                         int             height)
93 {
94     if (image->common.classify)
95         return image->common.classify (image, x, y, width, height);
96     else
97         return SOURCE_IMAGE_CLASS_UNKNOWN;
98 }
99
100 #define READ_ACCESS(f) ((image->common.read_func)? f##_accessors : f)
101
102 static void fbFetchSolid(bits_image_t * image, int x, int y, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
103 {
104     uint32_t color;
105     uint32_t *end;
106     fetchPixelProc32 fetch = READ_ACCESS(pixman_fetchPixelProcForPicture32)(image);
107
108     color = fetch(image, 0, 0);
109
110     end = buffer + width;
111     while (buffer < end)
112         *(buffer++) = color;
113 }
114
115 static void fbFetchSolid64(bits_image_t * image, int x, int y, int width, uint64_t *buffer, void *unused, uint32_t unused2)
116 {
117     uint64_t color;
118     uint64_t *end;
119     fetchPixelProc64 fetch = READ_ACCESS(pixman_fetchPixelProcForPicture64)(image);
120
121     color = fetch(image, 0, 0);
122
123     end = buffer + width;
124     while (buffer < end)
125         *(buffer++) = color;
126 }
127
128 static void fbFetch(bits_image_t * image, int x, int y, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
129 {
130     fetchProc32 fetch = READ_ACCESS(pixman_fetchProcForPicture32)(image);
131
132     fetch(image, x, y, width, buffer);
133 }
134
135 static void fbFetch64(bits_image_t * image, int x, int y, int width, uint64_t *buffer, void *unused, uint32_t unused2)
136 {
137     fetchProc64 fetch = READ_ACCESS(pixman_fetchProcForPicture64)(image);
138
139     fetch(image, x, y, width, buffer);
140 }
141
142 scanFetchProc
143 _pixman_image_get_fetcher (pixman_image_t *image,
144                            int             wide)
145 {
146     if (IS_SOURCE_IMAGE (image))
147     {
148         if (wide)
149             return (scanFetchProc)pixmanFetchSourcePict64;
150         else
151             return (scanFetchProc)pixmanFetchSourcePict;
152     }
153     else
154     {
155         bits_image_t *bits = (bits_image_t *)image;
156
157         if (bits->common.alpha_map)
158         {
159             if (wide)
160                 return (scanFetchProc)READ_ACCESS(fbFetchExternalAlpha64);
161             else
162                 return (scanFetchProc)READ_ACCESS(fbFetchExternalAlpha);
163         }
164         else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) &&
165                  bits->width == 1 &&
166                  bits->height == 1)
167         {
168             if (wide)
169                 return (scanFetchProc)fbFetchSolid64;
170             else
171                 return (scanFetchProc)fbFetchSolid;
172         }
173         else if (!bits->common.transform && bits->common.filter != PIXMAN_FILTER_CONVOLUTION
174                 && bits->common.repeat != PIXMAN_REPEAT_PAD && bits->common.repeat != PIXMAN_REPEAT_REFLECT)
175         {
176             if (wide)
177                 return (scanFetchProc)fbFetch64;
178             else
179                 return (scanFetchProc)fbFetch;
180         }
181         else
182         {
183             if (wide)
184                 return (scanFetchProc)READ_ACCESS(fbFetchTransformed64);
185             else
186                 return (scanFetchProc)READ_ACCESS(fbFetchTransformed);
187         }
188     }
189 }
190
191
192
193 #define WRITE_ACCESS(f) ((image->common.write_func)? f##_accessors : f)
194
195 static void
196 fbStore(bits_image_t * image, int x, int y, int width, uint32_t *buffer)
197 {
198     uint32_t *bits;
199     int32_t stride;
200     storeProc32 store = WRITE_ACCESS(pixman_storeProcForPicture32)(image);
201     const pixman_indexed_t * indexed = image->indexed;
202
203     bits = image->bits;
204     stride = image->rowstride;
205     bits += y*stride;
206     store((pixman_image_t *)image, bits, buffer, x, width, indexed);
207 }
208
209 static void
210 fbStore64(bits_image_t * image, int x, int y, int width, uint64_t *buffer)
211 {
212     uint32_t *bits;
213     int32_t stride;
214     storeProc64 store = WRITE_ACCESS(pixman_storeProcForPicture64)(image);
215     const pixman_indexed_t * indexed = image->indexed;
216
217     bits = image->bits;
218     stride = image->rowstride;
219     bits += y*stride;
220     store((pixman_image_t *)image, bits, buffer, x, width, indexed);
221 }
222
223 scanStoreProc
224 _pixman_image_get_storer (pixman_image_t *image,
225                           int             wide)
226 {
227     if (image->common.alpha_map)
228     {
229         if (wide)
230             return (scanStoreProc)WRITE_ACCESS(fbStoreExternalAlpha64);
231         else
232             return (scanStoreProc)WRITE_ACCESS(fbStoreExternalAlpha);
233     }
234     else
235     {
236         if (wide)
237             return (scanStoreProc)fbStore64;
238         else
239             return (scanStoreProc)fbStore;
240     }
241 }
242
243 static void
244 image_property_changed (pixman_image_t *image)
245 {
246     image->common.property_changed (image);
247 }
248
249 /* Ref Counting */
250 PIXMAN_EXPORT pixman_image_t *
251 pixman_image_ref (pixman_image_t *image)
252 {
253     image->common.ref_count++;
254
255     return image;
256 }
257
258 /* returns TRUE when the image is freed */
259 PIXMAN_EXPORT pixman_bool_t
260 pixman_image_unref (pixman_image_t *image)
261 {
262     image_common_t *common = (image_common_t *)image;
263
264     common->ref_count--;
265
266     if (common->ref_count == 0)
267     {
268         pixman_region32_fini (&common->clip_region);
269         pixman_region32_fini (&common->full_region);
270
271         if (common->transform)
272             free (common->transform);
273
274         if (common->filter_params)
275             free (common->filter_params);
276
277         if (common->alpha_map)
278             pixman_image_unref ((pixman_image_t *)common->alpha_map);
279
280 #if 0
281         if (image->type == BITS && image->bits.indexed)
282             free (image->bits.indexed);
283 #endif
284
285 #if 0
286         memset (image, 0xaa, sizeof (pixman_image_t));
287 #endif
288         if (image->type == LINEAR || image->type == RADIAL || image->type == CONICAL)
289         {
290             if (image->gradient.stops)
291                 free (image->gradient.stops);
292         }
293
294
295         if (image->type == BITS && image->bits.free_me)
296             free (image->bits.free_me);
297
298         free (image);
299
300         return TRUE;
301     }
302
303     return FALSE;
304 }
305
306 /* Constructors */
307
308 void
309 _pixman_image_reset_clip_region (pixman_image_t *image)
310 {
311     pixman_region32_fini (&image->common.clip_region);
312
313     if (image->type == BITS)
314     {
315         pixman_region32_init_rect (&image->common.clip_region, 0, 0,
316                                    image->bits.width, image->bits.height);
317     }
318     else
319     {
320         pixman_region32_init (&image->common.clip_region);
321     }
322 }
323
324 PIXMAN_EXPORT pixman_bool_t
325 pixman_image_set_clip_region32 (pixman_image_t *image,
326                                 pixman_region32_t *region)
327 {
328     image_common_t *common = (image_common_t *)image;
329     pixman_bool_t result;
330
331     if (region)
332     {
333         result = pixman_region32_copy (&common->clip_region, region);
334     }
335     else
336     {
337         _pixman_image_reset_clip_region (image);
338
339         result = TRUE;
340     }
341
342     image_property_changed (image);
343
344     return result;
345 }
346
347
348 PIXMAN_EXPORT pixman_bool_t
349 pixman_image_set_clip_region (pixman_image_t    *image,
350                               pixman_region16_t *region)
351 {
352     image_common_t *common = (image_common_t *)image;
353     pixman_bool_t result;
354
355     if (region)
356     {
357         result = pixman_region32_copy_from_region16 (&common->clip_region, region);
358     }
359     else
360     {
361         _pixman_image_reset_clip_region (image);
362
363         result = TRUE;
364     }
365
366     image_property_changed (image);
367
368     return result;
369 }
370
371 /* Sets whether the clip region includes a clip region set by the client
372  */
373 PIXMAN_EXPORT void
374 pixman_image_set_has_client_clip (pixman_image_t *image,
375                                   pixman_bool_t   client_clip)
376 {
377     image->common.has_client_clip = client_clip;
378
379     image_property_changed (image);
380 }
381
382 PIXMAN_EXPORT pixman_bool_t
383 pixman_image_set_transform (pixman_image_t           *image,
384                             const pixman_transform_t *transform)
385 {
386     static const pixman_transform_t id =
387     {
388         { { pixman_fixed_1, 0, 0 },
389           { 0, pixman_fixed_1, 0 },
390           { 0, 0, pixman_fixed_1 }
391         }
392     };
393
394     image_common_t *common = (image_common_t *)image;
395     pixman_bool_t result;
396
397     if (common->transform == transform)
398         return TRUE;
399
400     if (memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
401     {
402         free(common->transform);
403         common->transform = NULL;
404         result = TRUE;
405         goto out;
406     }
407
408     if (common->transform == NULL)
409         common->transform = malloc (sizeof (pixman_transform_t));
410
411     if (common->transform == NULL)
412     {
413         result = FALSE;
414         goto out;
415     }
416
417     memcpy(common->transform, transform, sizeof(pixman_transform_t));
418
419 out:
420     image_property_changed (image);
421     
422     return TRUE;
423 }
424
425 PIXMAN_EXPORT void
426 pixman_image_set_repeat (pixman_image_t  *image,
427                          pixman_repeat_t  repeat)
428 {
429     image->common.repeat = repeat;
430
431     image_property_changed (image);
432 }
433
434 PIXMAN_EXPORT pixman_bool_t
435 pixman_image_set_filter (pixman_image_t       *image,
436                          pixman_filter_t       filter,
437                          const pixman_fixed_t *params,
438                          int                   n_params)
439 {
440     image_common_t *common = (image_common_t *)image;
441     pixman_fixed_t *new_params;
442
443     if (params == common->filter_params && filter == common->filter)
444         return TRUE;
445
446     new_params = NULL;
447     if (params)
448     {
449         new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
450         if (!new_params)
451             return FALSE;
452
453         memcpy (new_params,
454                 params, n_params * sizeof (pixman_fixed_t));
455     }
456
457     common->filter = filter;
458
459     if (common->filter_params)
460         free (common->filter_params);
461
462     common->filter_params = new_params;
463     common->n_filter_params = n_params;
464
465     image_property_changed (image);
466     return TRUE;
467 }
468
469 PIXMAN_EXPORT void
470 pixman_image_set_source_clipping (pixman_image_t  *image,
471                                   pixman_bool_t    source_clipping)
472 {
473     image_common_t *common = &image->common;
474
475     if (source_clipping)
476         common->src_clip = &common->clip_region;
477     else
478         common->src_clip = &common->full_region;
479
480     image_property_changed (image);
481 }
482
483 /* Unlike all the other property setters, this function does not
484  * copy the content of indexed. Doing this copying is simply
485  * way, way too expensive.
486  */
487 PIXMAN_EXPORT void
488 pixman_image_set_indexed (pixman_image_t         *image,
489                           const pixman_indexed_t *indexed)
490 {
491     bits_image_t *bits = (bits_image_t *)image;
492
493     bits->indexed = indexed;
494
495     image_property_changed (image);
496 }
497
498 PIXMAN_EXPORT void
499 pixman_image_set_alpha_map (pixman_image_t *image,
500                             pixman_image_t *alpha_map,
501                             int16_t         x,
502                             int16_t         y)
503 {
504     image_common_t *common = (image_common_t *)image;
505
506     return_if_fail (!alpha_map || alpha_map->type == BITS);
507
508     if (common->alpha_map != (bits_image_t *)alpha_map)
509     {
510         if (common->alpha_map)
511             pixman_image_unref ((pixman_image_t *)common->alpha_map);
512
513         if (alpha_map)
514             common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
515         else
516             common->alpha_map = NULL;
517     }
518
519     common->alpha_origin.x = x;
520     common->alpha_origin.y = y;
521
522     image_property_changed (image);
523 }
524
525 PIXMAN_EXPORT void
526 pixman_image_set_component_alpha   (pixman_image_t       *image,
527                                     pixman_bool_t         component_alpha)
528 {
529     image->common.component_alpha = component_alpha;
530
531     image_property_changed (image);
532 }
533
534
535 PIXMAN_EXPORT void
536 pixman_image_set_accessors (pixman_image_t             *image,
537                             pixman_read_memory_func_t   read_func,
538                             pixman_write_memory_func_t  write_func)
539 {
540     return_if_fail (image != NULL);
541
542     image->common.read_func = read_func;
543     image->common.write_func = write_func;
544
545     image_property_changed (image);
546 }
547
548 PIXMAN_EXPORT uint32_t *
549 pixman_image_get_data (pixman_image_t *image)
550 {
551     if (image->type == BITS)
552         return image->bits.bits;
553
554     return NULL;
555 }
556
557 PIXMAN_EXPORT int
558 pixman_image_get_width (pixman_image_t *image)
559 {
560     if (image->type == BITS)
561         return image->bits.width;
562
563     return 0;
564 }
565
566 PIXMAN_EXPORT int
567 pixman_image_get_height (pixman_image_t *image)
568 {
569     if (image->type == BITS)
570         return image->bits.height;
571
572     return 0;
573 }
574
575 PIXMAN_EXPORT int
576 pixman_image_get_stride (pixman_image_t *image)
577 {
578     if (image->type == BITS)
579         return image->bits.rowstride * (int) sizeof (uint32_t);
580
581     return 0;
582 }
583
584 PIXMAN_EXPORT int
585 pixman_image_get_depth (pixman_image_t *image)
586 {
587     if (image->type == BITS)
588         return PIXMAN_FORMAT_DEPTH (image->bits.format);
589
590     return 0;
591 }
592
593 static uint32_t
594 color_to_uint32 (const pixman_color_t *color)
595 {
596     return
597         (color->alpha >> 8 << 24) |
598         (color->red >> 8 << 16) |
599         (color->green & 0xff00) |
600         (color->blue >> 8);
601 }
602
603 static pixman_bool_t
604 color_to_pixel (pixman_color_t *color,
605                 uint32_t       *pixel,
606                 pixman_format_code_t format)
607 {
608     uint32_t c = color_to_uint32 (color);
609
610     if (!(format == PIXMAN_a8r8g8b8     ||
611           format == PIXMAN_x8r8g8b8     ||
612           format == PIXMAN_a8b8g8r8     ||
613           format == PIXMAN_x8b8g8r8     ||
614           format == PIXMAN_b8g8r8a8     ||
615           format == PIXMAN_b8g8r8x8     ||
616           format == PIXMAN_r5g6b5       ||
617           format == PIXMAN_b5g6r5       ||
618           format == PIXMAN_a8))
619     {
620         return FALSE;
621     }
622
623     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
624     {
625         c = ((c & 0xff000000) >>  0) |
626             ((c & 0x00ff0000) >> 16) |
627             ((c & 0x0000ff00) >>  0) |
628             ((c & 0x000000ff) << 16);
629     }
630     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
631     {
632         c = ((c & 0xff000000) >> 24) |
633             ((c & 0x00ff0000) >>  8) |
634             ((c & 0x0000ff00) <<  8) |
635             ((c & 0x000000ff) << 24);
636     }
637
638     if (format == PIXMAN_a8)
639         c = c >> 24;
640     else if (format == PIXMAN_r5g6b5 ||
641              format == PIXMAN_b5g6r5)
642         c = cvt8888to0565 (c);
643
644 #if 0
645     printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
646     printf ("pixel: %x\n", c);
647 #endif
648
649     *pixel = c;
650     return TRUE;
651 }
652
653 PIXMAN_EXPORT pixman_bool_t
654 pixman_image_fill_rectangles (pixman_op_t                   op,
655                               pixman_image_t               *dest,
656                               pixman_color_t               *color,
657                               int                           n_rects,
658                               const pixman_rectangle16_t   *rects)
659 {
660     pixman_image_t *solid;
661     pixman_color_t c;
662     int i;
663
664     if (color->alpha == 0xffff)
665     {
666         if (op == PIXMAN_OP_OVER)
667             op = PIXMAN_OP_SRC;
668     }
669
670     if (op == PIXMAN_OP_CLEAR)
671     {
672         c.red = 0;
673         c.green = 0;
674         c.blue = 0;
675         c.alpha = 0;
676
677         color = &c;
678
679         op = PIXMAN_OP_SRC;
680     }
681
682     if (op == PIXMAN_OP_SRC)
683     {
684         uint32_t pixel;
685
686         if (color_to_pixel (color, &pixel, dest->bits.format))
687         {
688             for (i = 0; i < n_rects; ++i)
689             {
690                 pixman_region32_t fill_region;
691                 int n_boxes, j;
692                 pixman_box32_t *boxes;
693
694                 pixman_region32_init_rect (&fill_region, rects[i].x, rects[i].y, rects[i].width, rects[i].height);
695                 if (!pixman_region32_intersect (&fill_region,
696                                                 &fill_region,
697                                                 &dest->common.clip_region))
698                     return FALSE;
699
700
701                 boxes = pixman_region32_rectangles (&fill_region, &n_boxes);
702                 for (j = 0; j < n_boxes; ++j)
703                 {
704                     const pixman_box32_t *box = &(boxes[j]);
705                     pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
706                                  box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1,
707                                  pixel);
708                 }
709
710                 pixman_region32_fini (&fill_region);
711             }
712             return TRUE;
713         }
714     }
715
716     solid = pixman_image_create_solid_fill (color);
717     if (!solid)
718         return FALSE;
719
720     for (i = 0; i < n_rects; ++i)
721     {
722         const pixman_rectangle16_t *rect = &(rects[i]);
723
724         pixman_image_composite (op, solid, NULL, dest,
725                                 0, 0, 0, 0,
726                                 rect->x, rect->y,
727                                 rect->width, rect->height);
728     }
729
730     pixman_image_unref (solid);
731
732     return TRUE;
733 }
734
735 pixman_bool_t
736 pixman_image_can_get_solid (pixman_image_t *image)
737 {
738     if (image->type == SOLID)
739         return TRUE;
740
741     if (image->type != BITS     ||
742         image->bits.width != 1  ||
743         image->bits.height != 1)
744     {
745         return FALSE;
746     }
747
748     if (image->common.repeat != PIXMAN_REPEAT_NORMAL)
749         return FALSE;
750
751     switch (image->bits.format)
752     {
753     case PIXMAN_a8r8g8b8:
754     case PIXMAN_x8r8g8b8:
755     case PIXMAN_a8b8g8r8:
756     case PIXMAN_x8b8g8r8:
757     case PIXMAN_b8g8r8a8:
758     case PIXMAN_b8g8r8x8:
759     case PIXMAN_r8g8b8:
760     case PIXMAN_b8g8r8:
761     case PIXMAN_r5g6b5:
762     case PIXMAN_b5g6r5:
763         return TRUE;
764     default:
765         return FALSE;
766     }
767 }
768
769 pixman_bool_t
770 pixman_image_is_opaque(pixman_image_t *image)
771 {
772     int i = 0;
773     int gradientNumberOfColors = 0;
774
775     if(image->common.alpha_map)
776         return FALSE;
777
778     switch(image->type)
779     {
780     case BITS:
781         if(PIXMAN_FORMAT_A(image->bits.format))
782             return FALSE;
783         break;
784
785     case LINEAR:
786     case CONICAL:
787     case RADIAL:
788         gradientNumberOfColors = image->gradient.n_stops;
789         i=0;
790         while(i<gradientNumberOfColors)
791         {
792             if(image->gradient.stops[i].color.alpha != 0xffff)
793                 return FALSE;
794             i++;
795         }
796         break;
797
798     case SOLID:
799          if(Alpha(image->solid.color) != 0xff)
800             return FALSE;
801         break;
802     }
803
804     /* Convolution filters can introduce translucency if the sum of the weights
805        is lower than 1. */
806     if (image->common.filter == PIXMAN_FILTER_CONVOLUTION)
807          return FALSE;
808
809     if (image->common.repeat == PIXMAN_REPEAT_NONE)
810     {
811         if (image->common.filter != PIXMAN_FILTER_NEAREST)
812             return FALSE;
813
814         if (image->common.transform)
815             return FALSE;
816
817         /* Gradients do not necessarily cover the entire compositing area */
818         if (image->type == LINEAR || image->type == CONICAL || image->type == RADIAL)
819             return FALSE;
820     }
821
822      return TRUE;
823 }