LCOV - code coverage report
Current view: top level - evg - raster_rgb.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 187 204 91.7 %
Date: 2021-04-29 23:48:07 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2019
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / software 2D rasterizer module
       9             :  *
      10             :  *  GPAC is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU Lesser General Public License as published by
      12             :  *  the Free Software Foundation; either version 2, or (at your option)
      13             :  *  any later version.
      14             :  *
      15             :  *  GPAC is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU Lesser General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU Lesser General Public
      21             :  *  License along with this library; see the file COPYING.  If not, write to
      22             :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             :  *
      24             :  *
      25             :  *
      26             :  */
      27             : 
      28             : #include "rast_soft.h"
      29             : 
      30             : static s32
      31             : mul255(s32 a, s32 b)
      32             : {
      33    58564324 :         return ((a + 1) * b) >> 8;
      34             : }
      35             : 
      36             : 
      37             : /*
      38             :                         RGB part
      39             : */
      40             : 
      41     4365632 : void overmask_rgb(u32 src, u8 *dst, u32 alpha, GF_EVGSurface *surf)
      42             : {
      43     4365632 :         s32 srca = (src >> 24) & 0xff;
      44     4365632 :         s32 srcr = (src >> 16) & 0xff;
      45     4365632 :         s32 srcg = (src >> 8) & 0xff;
      46     4365632 :         s32 srcb = (src) & 0xff;
      47             : 
      48     4365632 :         s32 dstr = dst[surf->idx_r] & 0xFF;
      49     4365632 :         s32 dstg = dst[surf->idx_g] & 0xFF;
      50     4365632 :         s32 dstb = dst[surf->idx_b] & 0xFF;
      51             : 
      52     4365632 :         srca = mul255(srca, alpha);
      53     8731264 :         dst[surf->idx_r] = mul255(srca, srcr - dstr) + dstr;
      54     8731264 :         dst[surf->idx_g] = mul255(srca, srcg - dstg) + dstg;
      55     8731264 :         dst[surf->idx_b] = mul255(srca, srcb - dstb) + dstb;
      56     4365632 : }
      57             : 
      58     6832928 : static void overmask_rgb_const_run(u32 src, u8 *dst, s32 dst_pitch_x, u32 count, GF_EVGSurface *surf)
      59             : {
      60     6832928 :         s32 srca = (src >> 24) & 0xff;
      61     6832928 :         s32 srcr = (src >> 16) & 0xff;
      62     6832928 :         s32 srcg = (src >> 8) & 0xff;
      63     6832928 :         s32 srcb = (src) & 0xff;
      64             : 
      65    25084082 :         while (count) {
      66    11418226 :                 s32 dstr = dst[surf->idx_r];
      67    11418226 :                 s32 dstg = dst[surf->idx_g];
      68    11418226 :                 s32 dstb = dst[surf->idx_b];
      69    22836452 :                 dst[surf->idx_r] = (u8) mul255(srca, srcr - dstr) + dstr;
      70    22836452 :                 dst[surf->idx_g] = (u8) mul255(srca, srcg - dstg) + dstg;
      71    22836452 :                 dst[surf->idx_b] = (u8) mul255(srca, srcb - dstb) + dstb;
      72    11418226 :                 dst += dst_pitch_x;
      73    11418226 :                 count--;
      74             :         }
      75     6832928 : }
      76             : 
      77     3117931 : void evg_rgb_fill_single(s32 y, s32 x, u32 col, GF_EVGSurface *surf)
      78             : {
      79     3117931 :         u8 *dst = surf->pixels + y * surf->pitch_y + x * surf->pitch_x;
      80     3117931 :         u8 r = GF_COL_R(col);
      81     3117931 :         u8 g = GF_COL_G(col);
      82     3117931 :         u8 b = GF_COL_B(col);
      83     3117931 :         dst[surf->idx_r] = r;
      84     3117931 :         dst[surf->idx_g] = g;
      85     3117931 :         dst[surf->idx_b] = b;
      86     3117931 : }
      87             : 
      88      294619 : void evg_rgb_fill_single_a(s32 y, s32 x, u8 coverage, u32 col, GF_EVGSurface *surf)
      89             : {
      90      294619 :         u8 *dst = surf->pixels + y * surf->pitch_y + x * surf->pitch_x;
      91      294619 :         overmask_rgb(col, dst, coverage, surf);
      92      294619 : }
      93             : 
      94     1868607 : void evg_rgb_fill_const(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
      95             : {
      96     1868607 :         u32 col = surf->fill_col;
      97     1868607 :         u8 *dst = surf->pixels + y * surf->pitch_y;
      98             :         s32 i;
      99             :         u32 col_no_a, r, g, b;
     100             : 
     101     1868607 :         r = GF_COL_R(col);
     102     1868607 :         g = GF_COL_G(col);
     103             :         b = GF_COL_B(col);
     104             : 
     105     1868607 :         col_no_a = col & 0x00FFFFFF;
     106     9147955 :         for (i=0; i<count; i++) {
     107             :                 u32 a, fin, len;
     108             :                 char *p;
     109     7279348 :                 len = spans[i].len;
     110     7279348 :                 p = dst + spans[i].x * surf->pitch_x;
     111             : 
     112     7279348 :                 if (spans[i].coverage != 0xFF) {
     113    12950562 :                         a = mul255(0xFF, spans[i].coverage);
     114     6475281 :                         fin = (a<<24) | col_no_a;
     115     6475281 :                         overmask_rgb_const_run(fin, p, surf->pitch_x, len, surf);
     116             :                 } else {
     117    24526581 :                         while (len--) {
     118    23722514 :                                 p[surf->idx_r] = r;
     119    23722514 :                                 p[surf->idx_g] = g;
     120    23722514 :                                 p[surf->idx_b] = b;
     121    23722514 :                                 p += surf->pitch_x;
     122             :                         }
     123             :                 }
     124             :         }
     125     1868607 : }
     126             : 
     127       86579 : void evg_rgb_fill_const_a(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
     128             : {
     129       86579 :         u8 *dst = surf->pixels + y * surf->pitch_y;
     130       86579 :         u32 col = surf->fill_col;
     131             :         u32 a, fin;
     132             :         s32 i;
     133             : 
     134       86579 :         a = (col>>24)&0xFF;
     135       86579 :         if (surf->get_alpha) {
     136          16 :                 for (i=0; i<count; i++) {
     137             :                         u32 j;
     138         256 :                         for (j=0; j<spans[i].len; j++) {
     139         256 :                                 s32 x = spans[i].x + j;
     140         256 :                                 u8 aa = surf->get_alpha(surf->get_alpha_udta, a, x, y);
     141         512 :                                 fin = mul255(aa, spans[i].coverage);
     142         256 :                                 fin = (fin<<24) | (col&0x00FFFFFF);
     143         256 :                                 overmask_rgb_const_run(fin, dst + surf->pitch_x * x, surf->pitch_x, 1, surf);
     144             :                         }
     145             :                 }
     146             :         } else {
     147      357391 :                 for (i=0; i<count; i++) {
     148      714782 :                         fin = mul255(a, spans[i].coverage);
     149      357391 :                         fin = (fin<<24) | (col&0x00FFFFFF);
     150      357391 :                         overmask_rgb_const_run(fin, dst + surf->pitch_x * spans[i].x, surf->pitch_x, spans[i].len, surf);
     151             :                 }
     152             :         }
     153       86579 : }
     154             : 
     155             : 
     156      492153 : void evg_rgb_fill_var(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
     157             : {
     158      492153 :         u8 *dst = surf->pixels + y * surf->pitch_y;
     159             :         s32 i;
     160             : 
     161     2534301 :         for (i=0; i<count; i++) {
     162             :                 u8 spanalpha, col_a;
     163             :                 s32 x;
     164             :                 u32 len;
     165             :                 u32 *col;
     166     2042148 :                 len = spans[i].len;
     167     2042148 :                 spanalpha = spans[i].coverage;
     168     2042148 :                 evg_fill_run(surf->sten, surf, spans[i].x, y, len);
     169     2042148 :                 col = surf->stencil_pix_run;
     170     2042148 :                 x = surf->pitch_x * spans[i].x;
     171    34247269 :                 while (len--) {
     172    30162973 :                         col_a = GF_COL_A(*col);
     173    30162973 :                         if (col_a) {
     174    28150811 :                                 if ((spanalpha!=0xFF) || (col_a != 0xFF)) {
     175     4071013 :                                         overmask_rgb(*col, dst + x, spanalpha, surf);
     176             :                                 } else {
     177    24079798 :                                         dst[x + surf->idx_r] = GF_COL_R(*col);
     178    24079798 :                                         dst[x + surf->idx_g] = GF_COL_G(*col);
     179    24079798 :                                         dst[x + surf->idx_b] = GF_COL_B(*col);
     180             :                                 }
     181             :                         }
     182    30162973 :                         col++;
     183    30162973 :                         x += surf->pitch_x;
     184             :                 }
     185             :         }
     186      492153 : }
     187             : 
     188        2744 : GF_Err evg_surface_clear_rgb(GF_EVGSurface *surf, GF_IRect rc, GF_Color col)
     189             : {
     190             :         u32 x, y, w, h, sx, sy;
     191             :         s32 st;
     192             :         u8 r, g, b;
     193             :         u8 *o_data;
     194             :         GF_EVGSurface *_this = (GF_EVGSurface *)surf;
     195        2744 :         st = _this->pitch_y;
     196             : 
     197        2744 :         h = rc.height;
     198        2744 :         w = rc.width;
     199        2744 :         sx = rc.x;
     200        2744 :         sy = rc.y;
     201             : 
     202        2744 :         r = GF_COL_R(col);
     203        2744 :         g = GF_COL_G(col);
     204        2744 :         b = GF_COL_B(col);
     205             :         o_data = NULL;
     206      346393 :         for (y = 0; y < h; y++) {
     207      343649 :                 u8 *data = _this ->pixels + (y + sy) * st + _this->pitch_x*sx;
     208      343649 :                 if (!y) {
     209             :                         o_data = data;
     210      361595 :                         for (x = 0; x < w; x++) {
     211      361595 :                                 data[surf->idx_r] = r;
     212      361595 :                                 data[surf->idx_g] = g;
     213      361595 :                                 data[surf->idx_b] = b;
     214      361595 :                                 data += _this->pitch_x;
     215             :                         }
     216             :                 } else {
     217      340905 :                         memcpy(data, o_data, w*3);
     218             :                 }
     219             :         }
     220        2744 :         return GF_OK;
     221             : }
     222             : 
     223             : 
     224             : 
     225             : 
     226             : /*
     227             :                         grey part
     228             : */
     229             : 
     230             : static void overmask_grey(u32 src, char *dst, u32 alpha, u32 grey_type)
     231             : {
     232        5023 :         s32 srca = (src >> 24) & 0xff;
     233             :         u32 srcc;
     234        5023 :         s32 dstc = *dst;
     235             : 
     236        5023 :         if (grey_type==0) srcc = (src >> 16) & 0xff;
     237           0 :         else if (grey_type==1) srcc = (src >> 8) & 0xff;
     238           0 :         else srcc = (src) & 0xff;
     239             : 
     240             : 
     241        5023 :         srca = mul255(srca, alpha);
     242       10046 :         *dst = mul255(srca, srcc - dstc) + dstc;
     243             : }
     244             : 
     245             : static void overmask_grey_const_run(u8 srca, u8 srcc, char *dst, s32 dst_pitch_x, u32 count)
     246             : {
     247        4144 :         while (count) {
     248        2472 :                 u8 dstc = *(dst);
     249        4944 :                 *dst = (u8) mul255(srca, srcc - dstc) + dstc;
     250        2472 :                 dst += dst_pitch_x;
     251        2472 :                 count--;
     252             :         }
     253             : }
     254             : 
     255        8410 : void evg_grey_fill_single(s32 y, s32 x, u32 col, GF_EVGSurface *surf)
     256             : {
     257        8410 :         u8 *dst = surf->pixels + y * surf->pitch_y + x * surf->pitch_x;
     258             :         u8 c;
     259             : 
     260        8410 :         if (surf->grey_type==0) c = GF_COL_R(col);
     261           0 :         else if (surf->grey_type==1) c = GF_COL_G(col);
     262           0 :         else c = GF_COL_B(col);
     263        8410 :         *dst = c;
     264        8410 : }
     265             : 
     266         792 : void evg_grey_fill_single_a(s32 y, s32 x, u8 coverage, u32 col, GF_EVGSurface *surf)
     267             : {
     268         792 :         u8 *dst = surf->pixels + y * surf->pitch_y + x * surf->pitch_x;
     269         792 :         overmask_grey(col, dst, coverage, surf->grey_type);
     270         792 : }
     271             : 
     272         307 : void evg_grey_fill_const(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
     273             : {
     274         307 :         u32 col = surf->fill_col;
     275             :         u32 c;
     276         307 :         u8 *dst = surf->pixels + y * surf->pitch_y;
     277             :         s32 i;
     278             : 
     279         307 :         if (surf->grey_type==0) c = GF_COL_R(col);
     280           0 :         else if (surf->grey_type==1) c = GF_COL_G(col);
     281             :         else c = GF_COL_B(col);
     282             : 
     283        2032 :         for (i=0; i<count; i++) {
     284             :                 u32 a, len;
     285             :                 char *p;
     286        1725 :                 len = spans[i].len;
     287        1725 :                 p = dst + spans[i].x * surf->pitch_x;
     288             : 
     289        1725 :                 if (spans[i].coverage != 0xFF) {
     290        1428 :                         a = mul255(0xFF, spans[i].coverage);
     291        1428 :                         overmask_grey_const_run(a, c, p, surf->pitch_x, len);
     292             :                 } else {
     293        3226 :                         while (len--) {
     294        2929 :                                 *(p) = c;
     295        2929 :                                 p += surf->pitch_x;
     296             :                         }
     297             :                 }
     298             :         }
     299         307 : }
     300             : 
     301          56 : void evg_grey_fill_const_a(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
     302             : {
     303          56 :         u8 *dst = surf->pixels + y * surf->pitch_y;
     304             :         u32 a, fin;
     305             :         s32 i;
     306             :         u8 c;
     307             : 
     308          56 :         if (surf->grey_type==0) c = GF_COL_R(surf->fill_col);
     309           0 :         else if (surf->grey_type==1) c = GF_COL_G(surf->fill_col);
     310           0 :         else c = GF_COL_B(surf->fill_col);
     311             : 
     312          56 :         a = GF_COL_A(surf->fill_col);
     313          56 :         if (surf->get_alpha) {
     314           0 :                 for (i=0; i<count; i++) {
     315             :                         u32 j;
     316           0 :                         for (j=0; j<spans[i].len; j++) {
     317           0 :                                 s32 x = spans[i].x + j;
     318           0 :                                 u8 aa = surf->get_alpha(surf->get_alpha_udta, a, x, y);
     319           0 :                                 fin = mul255(aa, spans[i].coverage);
     320           0 :                                 overmask_grey_const_run(fin, c, dst + surf->pitch_x * x, surf->pitch_x, 1);
     321             :                         }
     322             :                 }
     323             :         } else {
     324         244 :                 for (i=0; i<count; i++) {
     325         244 :                         fin = mul255(a, spans[i].coverage);
     326         244 :                         overmask_grey_const_run(fin, c, dst + surf->pitch_x * spans[i].x, surf->pitch_x, spans[i].len);
     327             :                 }
     328             :         }
     329          56 : }
     330             : 
     331             : 
     332        1131 : void evg_grey_fill_var(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
     333             : {
     334        1131 :         u8 *dst = surf->pixels + y * surf->pitch_y;
     335             :         s32 i;
     336             : 
     337        2982 :         for (i=0; i<count; i++) {
     338             :                 u8 spanalpha, col_a;
     339             :                 s32 x;
     340             :                 u32 len;
     341             :                 u32 *col;
     342        1851 :                 len = spans[i].len;
     343        1851 :                 spanalpha = spans[i].coverage;
     344        1851 :                 evg_fill_run(surf->sten, surf, spans[i].x, y, len);
     345        1851 :                 col = surf->stencil_pix_run;
     346        1851 :                 x = surf->pitch_x * spans[i].x;
     347      123381 :                 while (len--) {
     348      119679 :                         col_a = GF_COL_A(*col);
     349      119679 :                         if (col_a) {
     350      107979 :                                 if ((spanalpha!=0xFF) || (col_a != 0xFF)) {
     351        4231 :                                         overmask_grey(*col, dst + x, spanalpha, surf->grey_type);
     352             :                                 } else {
     353             :                                         u8 c;
     354             : 
     355      103748 :                                         if (surf->grey_type==0) c = GF_COL_R(*col);
     356           0 :                                         else if (surf->grey_type==1) c = GF_COL_G(*col);
     357           0 :                                         else c = GF_COL_B(*col);
     358             : 
     359      103748 :                                         *(dst + x) = c;
     360             :                                 }
     361             :                         }
     362      119679 :                         col++;
     363      119679 :                         x += surf->pitch_x;
     364             :                 }
     365             :         }
     366        1131 : }
     367             : 
     368           5 : GF_Err evg_surface_clear_grey(GF_EVGSurface *surf, GF_IRect rc, GF_Color col)
     369             : {
     370             :         u32 y, w, h, sx, sy;
     371             :         s32 st;
     372             :         u8 r;
     373           5 :         st = surf->pitch_y;
     374             : 
     375           5 :         h = rc.height;
     376           5 :         w = rc.width;
     377           5 :         sx = rc.x;
     378           5 :         sy = rc.y;
     379             : 
     380           5 :         if (surf->grey_type==0) r = GF_COL_R(col);
     381           0 :         else if (surf->grey_type==1) r = GF_COL_G(col);
     382           0 :         else r = GF_COL_B(col);
     383             : 
     384         817 :         for (y = 0; y < h; y++) {
     385         812 :                 char *data = surf ->pixels + (y + sy) * st + surf->pitch_x*sx;
     386         812 :                 memset(data, r, w*surf->pitch_x);
     387             :         }
     388           5 :         return GF_OK;
     389             : }

Generated by: LCOV version 1.13