Subversion Repositories Kolibri OS

Rev

Rev 1891 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
  3.  *             2005 Lars Knoll & Zack Rusin, Trolltech
  4.  *             2008 Aaron Plattner, NVIDIA Corporation
  5.  * Copyright © 2000 SuSE, Inc.
  6.  * Copyright © 2007, 2009 Red Hat, Inc.
  7.  * Copyright © 2008 André Tupinambá <andrelrt@gmail.com>
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and its
  10.  * documentation for any purpose is hereby granted without fee, provided that
  11.  * the above copyright notice appear in all copies and that both that
  12.  * copyright notice and this permission notice appear in supporting
  13.  * documentation, and that the name of Keith Packard not be used in
  14.  * advertising or publicity pertaining to distribution of the software without
  15.  * specific, written prior permission.  Keith Packard makes no
  16.  * representations about the suitability of this software for any purpose.  It
  17.  * is provided "as is" without express or implied warranty.
  18.  *
  19.  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  20.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  21.  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
  22.  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  23.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  24.  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  25.  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  26.  * SOFTWARE.
  27.  */
  28.  
  29. #ifdef HAVE_CONFIG_H
  30. #include <config.h>
  31. #endif
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include "pixman-private.h"
  36. #include "pixman-combine32.h"
  37. #include "pixman-inlines.h"
  38.  
  39. static uint32_t *
  40. _pixman_image_get_scanline_generic_float (pixman_iter_t * iter,
  41.                                           const uint32_t *mask)
  42. {
  43.     pixman_iter_get_scanline_t fetch_32 = iter->data;
  44.     uint32_t *buffer = iter->buffer;
  45.  
  46.     fetch_32 (iter, NULL);
  47.  
  48.     pixman_expand_to_float ((argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);
  49.  
  50.     return iter->buffer;
  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.     {
  82.         repeat (image->common.repeat, &x0, image->width);
  83.         repeat (image->common.repeat, &y0, image->height);
  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.  
  109.     distx = pixman_fixed_to_bilinear_weight (x1);
  110.     disty = pixman_fixed_to_bilinear_weight (y1);
  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.     {
  119.         repeat (repeat_mode, &x1, width);
  120.         repeat (repeat_mode, &y1, height);
  121.         repeat (repeat_mode, &x2, width);
  122.         repeat (repeat_mode, &y2, height);
  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.  
  140. static uint32_t *
  141. bits_image_fetch_bilinear_no_repeat_8888 (pixman_iter_t *iter,
  142.                                           const uint32_t *mask)
  143. {
  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.  
  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))
  172.         return iter->buffer;
  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;
  178.     disty = pixman_fixed_to_bilinear_weight (y);
  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));
  239.         return iter->buffer;
  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.  
  287.         distx = pixman_fixed_to_bilinear_weight (x);
  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.  
  312.             distx = pixman_fixed_to_bilinear_weight (x);
  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.  
  336.             distx = pixman_fixed_to_bilinear_weight (x);
  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;
  351.  
  352.     return iter->buffer;
  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;
  370.     int srtot, sgtot, sbtot, satot;
  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.                 {
  396.                     repeat (repeat_mode, &rx, width);
  397.                     repeat (repeat_mode, &ry, height);
  398.  
  399.                     pixel = get_pixel (image, rx, ry, FALSE);
  400.                 }
  401.                 else
  402.                 {
  403.                     pixel = get_pixel (image, rx, ry, TRUE);
  404.                 }
  405.  
  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;
  410.             }
  411.  
  412.             params++;
  413.         }
  414.     }
  415.  
  416.     satot = (satot + 0x8000) >> 16;
  417.     srtot = (srtot + 0x8000) >> 16;
  418.     sgtot = (sgtot + 0x8000) >> 16;
  419.     sbtot = (sbtot + 0x8000) >> 16;
  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.  
  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.  
  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.  
  550.     case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
  551.         return bits_image_fetch_pixel_separable_convolution (image, x, y, get_pixel);
  552.         break;
  553.  
  554.     default:
  555.         break;
  556.     }
  557.  
  558.     return 0;
  559. }
  560.  
  561. static uint32_t *
  562. bits_image_fetch_affine_no_alpha (pixman_iter_t *  iter,
  563.                                   const uint32_t * mask)
  564. {
  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.  
  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))
  584.             return iter->buffer;
  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.     }
  609.  
  610.     return buffer;
  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.  
  654. static uint32_t *
  655. bits_image_fetch_general (pixman_iter_t  *iter,
  656.                           const uint32_t *mask)
  657. {
  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.  
  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))
  677.             return buffer;
  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.     }
  719.  
  720.     return buffer;
  721. }
  722.  
  723. typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x);
  724.  
  725. static force_inline void
  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
  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.  
  919.         distx = pixman_fixed_to_bilinear_weight (x1);
  920.         disty = pixman_fixed_to_bilinear_weight (y1);
  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.  
  933.             repeat (repeat_mode, &x1, width);
  934.             repeat (repeat_mode, &y1, height);
  935.             repeat (repeat_mode, &x2, width);
  936.             repeat (repeat_mode, &y2, height);
  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.  
  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.  
  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. {
  1117.     return convert_0565_to_0888 (*((uint16_t *)row + x));
  1118. }
  1119.  
  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.  
  1137. #define MAKE_BILINEAR_FETCHER(name, format, repeat_mode)                \
  1138.     static uint32_t *                                                   \
  1139.     bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t   *iter,   \
  1140.                                                const uint32_t * mask)   \
  1141.     {                                                                   \
  1142.         bits_image_fetch_bilinear_affine (iter->image,                  \
  1143.                                           iter->x, iter->y++,           \
  1144.                                           iter->width,                  \
  1145.                                           iter->buffer, mask,           \
  1146.                                           convert_ ## format,           \
  1147.                                           PIXMAN_ ## format,            \
  1148.                                           repeat_mode);                 \
  1149.         return iter->buffer;                                            \
  1150.     }
  1151.  
  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.     }
  1166.  
  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.  
  1189. static void
  1190. replicate_pixel_32 (bits_image_t *   bits,
  1191.                     int              x,
  1192.                     int              y,
  1193.                     int              width,
  1194.                     uint32_t *       buffer)
  1195. {
  1196.     uint32_t color;
  1197.     uint32_t *end;
  1198.  
  1199.     color = bits->fetch_pixel_32 (bits, x, y);
  1200.  
  1201.     end = buffer + width;
  1202.     while (buffer < end)
  1203.         *(buffer++) = color;
  1204. }
  1205.  
  1206. static void
  1207. replicate_pixel_float (bits_image_t *   bits,
  1208.                        int              x,
  1209.                        int              y,
  1210.                        int              width,
  1211.                        uint32_t *       b)
  1212. {
  1213.     argb_t color;
  1214.     argb_t *buffer = (argb_t *)b;
  1215.     argb_t *end;
  1216.  
  1217.     color = bits->fetch_pixel_float (bits, x, y);
  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.     {
  1236.         memset (buffer, 0, width * (wide? sizeof (argb_t) : 4));
  1237.         return;
  1238.     }
  1239.  
  1240.     if (x < 0)
  1241.     {
  1242.         w = MIN (width, -x);
  1243.  
  1244.         memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4));
  1245.  
  1246.         width -= w;
  1247.         buffer += w * (wide? 4 : 1);
  1248.         x += w;
  1249.     }
  1250.  
  1251.     if (x < image->width)
  1252.     {
  1253.         w = MIN (width, image->width - x);
  1254.  
  1255.         if (wide)
  1256.             image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL);
  1257.         else
  1258.             image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL);
  1259.  
  1260.         width -= w;
  1261.         buffer += w * (wide? 4 : 1);
  1262.         x += w;
  1263.     }
  1264.  
  1265.     memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4));
  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.  
  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.  
  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)
  1304.             image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL);
  1305.         else
  1306.             image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL);
  1307.  
  1308.         buffer += w * (wide? 4 : 1);
  1309.         x += w;
  1310.         width -= w;
  1311.     }
  1312. }
  1313.  
  1314. static uint32_t *
  1315. bits_image_fetch_untransformed_32 (pixman_iter_t * iter,
  1316.                                    const uint32_t *mask)
  1317. {
  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.  
  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.     }
  1334.  
  1335.     iter->y++;
  1336.     return buffer;
  1337. }
  1338.  
  1339. static uint32_t *
  1340. bits_image_fetch_untransformed_float (pixman_iter_t * iter,
  1341.                                       const uint32_t *mask)
  1342. {
  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.  
  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.     }
  1359.  
  1360.     iter->y++;
  1361.     return buffer;
  1362. }
  1363.  
  1364. typedef struct
  1365. {
  1366.     pixman_format_code_t        format;
  1367.     uint32_t                    flags;
  1368.     pixman_iter_get_scanline_t  get_scanline_32;
  1369.     pixman_iter_get_scanline_t  get_scanline_float;
  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,
  1381.       bits_image_fetch_untransformed_float
  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,
  1397.       _pixman_image_get_scanline_generic_float
  1398.     },
  1399.  
  1400.     { PIXMAN_x8r8g8b8,
  1401.       FAST_BILINEAR_FLAGS,
  1402.       bits_image_fetch_bilinear_no_repeat_8888,
  1403.       _pixman_image_get_scanline_generic_float
  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.  
  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.  
  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,                        \
  1438.       _pixman_image_get_scanline_generic_float                          \
  1439.     },
  1440.  
  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.     },
  1447.  
  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.  
  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,
  1474.       _pixman_image_get_scanline_generic_float
  1475.     },
  1476.  
  1477.     /* General */
  1478.     { PIXMAN_any,
  1479.       0,
  1480.       bits_image_fetch_general,
  1481.       _pixman_image_get_scanline_generic_float
  1482.     },
  1483.  
  1484.     { PIXMAN_null },
  1485. };
  1486.  
  1487. static void
  1488. bits_image_property_changed (pixman_image_t *image)
  1489. {
  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;
  1497.     uint32_t flags = image->common.flags;
  1498.     const fetcher_info_t *info;
  1499.  
  1500.     for (info = fetcher_info; info->format != PIXMAN_null; ++info)
  1501.     {
  1502.         if ((info->format == format || info->format == PIXMAN_any)      &&
  1503.             (info->flags & flags) == info->flags)
  1504.         {
  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;
  1515.         }
  1516.     }
  1517.  
  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.         }
  1555.     }
  1556.  
  1557.     return iter->buffer;
  1558. }
  1559.  
  1560. static uint32_t *
  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 *
  1667. create_bits (pixman_format_code_t format,
  1668.              int                  width,
  1669.              int                  height,
  1670.              int *                rowstride_bytes,
  1671.              pixman_bool_t        clear)
  1672. {
  1673.     int stride;
  1674.     size_t buf_size;
  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);
  1683.     if (_pixman_multiply_overflows_int (width, bpp))
  1684.         return NULL;
  1685.  
  1686.     stride = width * bpp;
  1687.     if (_pixman_addition_overflows_int (stride, 0x1f))
  1688.         return NULL;
  1689.  
  1690.     stride += 0x1f;
  1691.     stride >>= 5;
  1692.  
  1693.     stride *= sizeof (uint32_t);
  1694.  
  1695.     if (_pixman_multiply_overflows_size (height, stride))
  1696.         return NULL;
  1697.  
  1698.     buf_size = height * stride;
  1699.  
  1700.     if (rowstride_bytes)
  1701.         *rowstride_bytes = stride;
  1702.  
  1703.     if (clear)
  1704.         return calloc (buf_size, 1);
  1705.     else
  1706.         return malloc (buf_size);
  1707. }
  1708.  
  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)
  1717. {
  1718.     uint32_t *free_me = NULL;
  1719.  
  1720.     if (!bits && width && height)
  1721.     {
  1722.         int rowstride_bytes;
  1723.  
  1724.         free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear);
  1725.  
  1726.         if (!bits)
  1727.             return FALSE;
  1728.  
  1729.         rowstride = rowstride_bytes / (int) sizeof (uint32_t);
  1730.     }
  1731.  
  1732.     _pixman_image_init (image);
  1733.  
  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;
  1742.     image->bits.rowstride = rowstride;
  1743.     image->bits.indexed = NULL;
  1744.  
  1745.     image->common.property_changed = bits_image_property_changed;
  1746.  
  1747.     _pixman_image_reset_clip_region (image);
  1748.  
  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.  
  1782.     return image;
  1783. }
  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. }
  1809.