summaryrefslogtreecommitdiff
path: root/src/lib/evas/filters/evas_filter_transform.c
blob: bc9f65d9149a0197917daa36aa62862582a0a00c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "evas_filter_private.h"

static Eina_Bool
_vflip_cpu(Evas_Filter_Command *cmd)
{
   size_t datasize, stride;
   DATA8 *in, *out, *span;
   int w, h, sy, dy, oy, center, t, b, objh;
   int s0, s1, d0, d1;

   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);

   w = cmd->input->w;
   h = cmd->input->h;
   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->w == w, EINA_FALSE);
   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->h == h, EINA_FALSE);
   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->alpha_only == cmd->input->alpha_only, EINA_FALSE);

   in = ((RGBA_Image *) cmd->input->backing)->mask.data;
   out = ((RGBA_Image *) cmd->output->backing)->mask.data;
   datasize = cmd->input->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
   stride = w * datasize;

   oy = cmd->draw.oy;
   t = cmd->ctx->padt;
   b = cmd->ctx->padb;
   objh = h - t - b;
   center = t + objh / 2 + oy;

   s0 = t;
   s1 = h - b - 1;
   if (oy >= 0)
     {
        d0 = center + (objh / 2) + oy;
        d1 = center - (objh / 2) - oy;
     }
   else
     {
        d0 = center + (objh / 2) - oy;
        d1 = center - (objh / 2) + oy;
     }

   if (in == out)
     {
        span = malloc(stride);
        if (!span) return EINA_FALSE;
     }

   for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--)
     {
        DATA8* src = in + stride * sy;
        DATA8* dst = out + stride * dy;

        if (in == out)
          {
             if (src == dst) break;
             memcpy(span, dst, stride);
             memcpy(dst, src, stride);
             memcpy(src, span, stride);
             if (sy >= center) break;
          }
        else
          memcpy(dst, src, stride);
     }

   return EINA_TRUE;
}

Evas_Filter_Apply_Func
evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd)
{
   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);

   switch (cmd->transform.flags)
     {
      case EVAS_FILTER_TRANSFORM_VFLIP:
        return _vflip_cpu;
      default:
        CRI("Unknown transform flag %d", (int) cmd->transform.flags);
        return NULL;
     }
}