Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include "fitz.h"
  2.  
  3. /* PDF 1.4 blend modes. These are slow. */
  4.  
  5. typedef unsigned char byte;
  6.  
  7. static const char *fz_blendmode_names[] =
  8. {
  9.         "Normal",
  10.         "Multiply",
  11.         "Screen",
  12.         "Overlay",
  13.         "Darken",
  14.         "Lighten",
  15.         "ColorDodge",
  16.         "ColorBurn",
  17.         "HardLight",
  18.         "SoftLight",
  19.         "Difference",
  20.         "Exclusion",
  21.         "Hue",
  22.         "Saturation",
  23.         "Color",
  24.         "Luminosity",
  25. };
  26.  
  27. int fz_find_blendmode(char *name)
  28. {
  29.         int i;
  30.         for (i = 0; i < nelem(fz_blendmode_names); i++)
  31.                 if (!strcmp(name, fz_blendmode_names[i]))
  32.                         return i;
  33.         return FZ_BLEND_NORMAL;
  34. }
  35.  
  36. char *fz_blendmode_name(int blendmode)
  37. {
  38.         if (blendmode >= 0 && blendmode < nelem(fz_blendmode_names))
  39.                 return (char*)fz_blendmode_names[blendmode];
  40.         return "Normal";
  41. }
  42.  
  43. /* Separable blend modes */
  44.  
  45. static inline int fz_screen_byte(int b, int s)
  46. {
  47.         return b + s - fz_mul255(b, s);
  48. }
  49.  
  50. static inline int fz_hard_light_byte(int b, int s)
  51. {
  52.         int s2 = s << 1;
  53.         if (s <= 127)
  54.                 return fz_mul255(b, s2);
  55.         else
  56.                 return fz_screen_byte(b, s2 - 255);
  57. }
  58.  
  59. static inline int fz_overlay_byte(int b, int s)
  60. {
  61.         return fz_hard_light_byte(s, b); /* note swapped order */
  62. }
  63.  
  64. static inline int fz_darken_byte(int b, int s)
  65. {
  66.         return MIN(b, s);
  67. }
  68.  
  69. static inline int fz_lighten_byte(int b, int s)
  70. {
  71.         return MAX(b, s);
  72. }
  73.  
  74. static inline int fz_color_dodge_byte(int b, int s)
  75. {
  76.         s = 255 - s;
  77.         if (b == 0)
  78.                 return 0;
  79.         else if (b >= s)
  80.                 return 255;
  81.         else
  82.                 return (0x1fe * b + s) / (s << 1);
  83. }
  84.  
  85. static inline int fz_color_burn_byte(int b, int s)
  86. {
  87.         b = 255 - b;
  88.         if (b == 0)
  89.                 return 255;
  90.         else if (b >= s)
  91.                 return 0;
  92.         else
  93.                 return 0xff - (0x1fe * b + s) / (s << 1);
  94. }
  95.  
  96. static inline int fz_soft_light_byte(int b, int s)
  97. {
  98.         /* review this */
  99.         if (s < 128) {
  100.                 return b - fz_mul255(fz_mul255((255 - (s<<1)), b), 255 - b);
  101.         }
  102.         else {
  103.                 int dbd;
  104.                 if (b < 64)
  105.                         dbd = fz_mul255(fz_mul255((b << 4) - 12, b) + 4, b);
  106.                 else
  107.                         dbd = (int)sqrtf(255.0f * b);
  108.                 return b + fz_mul255(((s<<1) - 255), (dbd - b));
  109.         }
  110. }
  111.  
  112. static inline int fz_difference_byte(int b, int s)
  113. {
  114.         return ABS(b - s);
  115. }
  116.  
  117. static inline int fz_exclusion_byte(int b, int s)
  118. {
  119.         return b + s - (fz_mul255(b, s)<<1);
  120. }
  121.  
  122. /* Non-separable blend modes */
  123.  
  124. static void
  125. fz_luminosity_rgb(int *rd, int *gd, int *bd, int rb, int gb, int bb, int rs, int gs, int bs)
  126. {
  127.         int delta, scale;
  128.         int r, g, b, y;
  129.  
  130.         /* 0.3, 0.59, 0.11 in fixed point */
  131.         delta = ((rs - rb) * 77 + (gs - gb) * 151 + (bs - bb) * 28 + 0x80) >> 8;
  132.         r = rb + delta;
  133.         g = gb + delta;
  134.         b = bb + delta;
  135.  
  136.         if ((r | g | b) & 0x100)
  137.         {
  138.                 y = (rs * 77 + gs * 151 + bs * 28 + 0x80) >> 8;
  139.                 if (delta > 0)
  140.                 {
  141.                         int max;
  142.                         max = MAX(r, MAX(g, b));
  143.                         scale = ((255 - y) << 16) / (max - y);
  144.                 }
  145.                 else
  146.                 {
  147.                         int min;
  148.                         min = MIN(r, MIN(g, b));
  149.                         scale = (y << 16) / (y - min);
  150.                 }
  151.                 r = y + (((r - y) * scale + 0x8000) >> 16);
  152.                 g = y + (((g - y) * scale + 0x8000) >> 16);
  153.                 b = y + (((b - y) * scale + 0x8000) >> 16);
  154.         }
  155.  
  156.         *rd = r;
  157.         *gd = g;
  158.         *bd = b;
  159. }
  160.  
  161. static void
  162. fz_saturation_rgb(int *rd, int *gd, int *bd, int rb, int gb, int bb, int rs, int gs, int bs)
  163. {
  164.         int minb, maxb;
  165.         int mins, maxs;
  166.         int y;
  167.         int scale;
  168.         int r, g, b;
  169.  
  170.         minb = MIN(rb, MIN(gb, bb));
  171.         maxb = MAX(rb, MAX(gb, bb));
  172.         if (minb == maxb)
  173.         {
  174.                 /* backdrop has zero saturation, avoid divide by 0 */
  175.                 *rd = gb;
  176.                 *gd = gb;
  177.                 *bd = gb;
  178.                 return;
  179.         }
  180.  
  181.         mins = MIN(rs, MIN(gs, bs));
  182.         maxs = MAX(rs, MAX(gs, bs));
  183.  
  184.         scale = ((maxs - mins) << 16) / (maxb - minb);
  185.         y = (rb * 77 + gb * 151 + bb * 28 + 0x80) >> 8;
  186.         r = y + ((((rb - y) * scale) + 0x8000) >> 16);
  187.         g = y + ((((gb - y) * scale) + 0x8000) >> 16);
  188.         b = y + ((((bb - y) * scale) + 0x8000) >> 16);
  189.  
  190.         if ((r | g | b) & 0x100)
  191.         {
  192.                 int scalemin, scalemax;
  193.                 int min, max;
  194.  
  195.                 min = MIN(r, MIN(g, b));
  196.                 max = MAX(r, MAX(g, b));
  197.  
  198.                 if (min < 0)
  199.                         scalemin = (y << 16) / (y - min);
  200.                 else
  201.                         scalemin = 0x10000;
  202.  
  203.                 if (max > 255)
  204.                         scalemax = ((255 - y) << 16) / (max - y);
  205.                 else
  206.                         scalemax = 0x10000;
  207.  
  208.                 scale = MIN(scalemin, scalemax);
  209.                 r = y + (((r - y) * scale + 0x8000) >> 16);
  210.                 g = y + (((g - y) * scale + 0x8000) >> 16);
  211.                 b = y + (((b - y) * scale + 0x8000) >> 16);
  212.         }
  213.  
  214.         *rd = r;
  215.         *gd = g;
  216.         *bd = b;
  217. }
  218.  
  219. static void
  220. fz_color_rgb(int *rr, int *rg, int *rb, int br, int bg, int bb, int sr, int sg, int sb)
  221. {
  222.         fz_luminosity_rgb(rr, rg, rb, sr, sg, sb, br, bg, bb);
  223. }
  224.  
  225. static void
  226. fz_hue_rgb(int *rr, int *rg, int *rb, int br, int bg, int bb, int sr, int sg, int sb)
  227. {
  228.         int tr, tg, tb;
  229.         fz_luminosity_rgb(&tr, &tg, &tb, sr, sg, sb, br, bg, bb);
  230.         fz_saturation_rgb(rr, rg, rb, tr, tg, tb, br, bg, bb);
  231. }
  232.  
  233. /* Blending loops */
  234.  
  235. void
  236. fz_blend_separable(byte * restrict bp, byte * restrict sp, int n, int w, int blendmode)
  237. {
  238.         int k;
  239.         int n1 = n - 1;
  240.         while (w--)
  241.         {
  242.                 int sa = sp[n1];
  243.                 int ba = bp[n1];
  244.                 int saba = fz_mul255(sa, ba);
  245.  
  246.                 /* ugh, division to get non-premul components */
  247.                 int invsa = sa ? 255 * 256 / sa : 0;
  248.                 int invba = ba ? 255 * 256 / ba : 0;
  249.  
  250.                 for (k = 0; k < n1; k++)
  251.                 {
  252.                         int sc = (sp[k] * invsa) >> 8;
  253.                         int bc = (bp[k] * invba) >> 8;
  254.                         int rc;
  255.  
  256.                         switch (blendmode)
  257.                         {
  258.                         default:
  259.                         case FZ_BLEND_NORMAL: rc = sc; break;
  260.                         case FZ_BLEND_MULTIPLY: rc = fz_mul255(bc, sc); break;
  261.                         case FZ_BLEND_SCREEN: rc = fz_screen_byte(bc, sc); break;
  262.                         case FZ_BLEND_OVERLAY: rc = fz_overlay_byte(bc, sc); break;
  263.                         case FZ_BLEND_DARKEN: rc = fz_darken_byte(bc, sc); break;
  264.                         case FZ_BLEND_LIGHTEN: rc = fz_lighten_byte(bc, sc); break;
  265.                         case FZ_BLEND_COLOR_DODGE: rc = fz_color_dodge_byte(bc, sc); break;
  266.                         case FZ_BLEND_COLOR_BURN: rc = fz_color_burn_byte(bc, sc); break;
  267.                         case FZ_BLEND_HARD_LIGHT: rc = fz_hard_light_byte(bc, sc); break;
  268.                         case FZ_BLEND_SOFT_LIGHT: rc = fz_soft_light_byte(bc, sc); break;
  269.                         case FZ_BLEND_DIFFERENCE: rc = fz_difference_byte(bc, sc); break;
  270.                         case FZ_BLEND_EXCLUSION: rc = fz_exclusion_byte(bc, sc); break;
  271.                         }
  272.  
  273.                         bp[k] = fz_mul255(255 - sa, bp[k]) + fz_mul255(255 - ba, sp[k]) + fz_mul255(saba, rc);
  274.                 }
  275.  
  276.                 bp[k] = ba + sa - saba;
  277.  
  278.                 sp += n;
  279.                 bp += n;
  280.         }
  281. }
  282.  
  283. void
  284. fz_blend_nonseparable(byte * restrict bp, byte * restrict sp, int w, int blendmode)
  285. {
  286.         while (w--)
  287.         {
  288.                 int rr, rg, rb;
  289.  
  290.                 int sa = sp[3];
  291.                 int ba = bp[3];
  292.                 int saba = fz_mul255(sa, ba);
  293.  
  294.                 /* ugh, division to get non-premul components */
  295.                 int invsa = sa ? 255 * 256 / sa : 0;
  296.                 int invba = ba ? 255 * 256 / ba : 0;
  297.  
  298.                 int sr = (sp[0] * invsa) >> 8;
  299.                 int sg = (sp[1] * invsa) >> 8;
  300.                 int sb = (sp[2] * invsa) >> 8;
  301.  
  302.                 int br = (bp[0] * invba) >> 8;
  303.                 int bg = (bp[1] * invba) >> 8;
  304.                 int bb = (bp[2] * invba) >> 8;
  305.  
  306.                 switch (blendmode)
  307.                 {
  308.                 default:
  309.                 case FZ_BLEND_HUE:
  310.                         fz_hue_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb);
  311.                         break;
  312.                 case FZ_BLEND_SATURATION:
  313.                         fz_saturation_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb);
  314.                         break;
  315.                 case FZ_BLEND_COLOR:
  316.                         fz_color_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb);
  317.                         break;
  318.                 case FZ_BLEND_LUMINOSITY:
  319.                         fz_luminosity_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb);
  320.                         break;
  321.                 }
  322.  
  323.                 bp[0] = fz_mul255(255 - sa, bp[0]) + fz_mul255(255 - ba, sp[0]) + fz_mul255(saba, rr);
  324.                 bp[1] = fz_mul255(255 - sa, bp[1]) + fz_mul255(255 - ba, sp[1]) + fz_mul255(saba, rg);
  325.                 bp[2] = fz_mul255(255 - sa, bp[2]) + fz_mul255(255 - ba, sp[2]) + fz_mul255(saba, rb);
  326.                 bp[3] = ba + sa - saba;
  327.  
  328.                 sp += 4;
  329.                 bp += 4;
  330.         }
  331. }
  332.  
  333. static void
  334. fz_blend_separable_nonisolated(byte * restrict bp, byte * restrict sp, int n, int w, int blendmode, byte * restrict hp, int alpha)
  335. {
  336.         int k;
  337.         int n1 = n - 1;
  338.  
  339.         if (alpha == 255 && blendmode == 0)
  340.         {
  341.                 /* In this case, the uncompositing and the recompositing
  342.                  * cancel one another out, and it's just a simple copy. */
  343.                 /* FIXME: Maybe we can avoid using the shape plane entirely
  344.                  * and just copy? */
  345.                 while (w--)
  346.                 {
  347.                         int ha = fz_mul255(*hp++, alpha); /* ha = shape_alpha */
  348.                         /* If ha == 0 then leave everything unchanged */
  349.                         if (ha != 0)
  350.                         {
  351.                                 for (k = 0; k < n; k++)
  352.                                 {
  353.                                         bp[k] = sp[k];
  354.                                 }
  355.                         }
  356.  
  357.                         sp += n;
  358.                         bp += n;
  359.                 }
  360.                 return;
  361.         }
  362.         while (w--)
  363.         {
  364.                 int ha = *hp++;
  365.                 int haa = fz_mul255(ha, alpha); /* ha = shape_alpha */
  366.                 /* If haa == 0 then leave everything unchanged */
  367.                 if (haa != 0)
  368.                 {
  369.                         int sa = sp[n1];
  370.                         int ba = bp[n1];
  371.                         int baha = fz_mul255(ba, haa);
  372.  
  373.                         /* ugh, division to get non-premul components */
  374.                         int invsa = sa ? 255 * 256 / sa : 0;
  375.                         int invba = ba ? 255 * 256 / ba : 0;
  376.  
  377.                         /* Calculate result_alpha */
  378.                         int ra = bp[n1] = ba - baha + haa;
  379.  
  380.                         /* Because we are a non-isolated group, we need to
  381.                          * 'uncomposite' before we blend (recomposite).
  382.                          * We assume that normal blending has been done inside
  383.                          * the group, so:   ra.rc = (1-ha).bc + ha.sc
  384.                          * A bit of rearrangement, and that gives us that:
  385.                          *  sc = (ra.rc - bc)/ha + bc
  386.                          * Now, the result of the blend was stored in src, so:
  387.                          */
  388.                         int invha = ha ? 255 * 256 / ha : 0;
  389.  
  390.                         if (ra != 0) for (k = 0; k < n1; k++)
  391.                         {
  392.                                 int sc = (sp[k] * invsa) >> 8;
  393.                                 int bc = (bp[k] * invba) >> 8;
  394.                                 int rc;
  395.  
  396.                                 /* Uncomposite */
  397.                                 sc = (((sc-bc)*invha)>>8) + bc;
  398.                                 if (sc < 0) sc = 0;
  399.                                 if (sc > 255) sc = 255;
  400.  
  401.                                 switch (blendmode)
  402.                                 {
  403.                                 default:
  404.                                 case FZ_BLEND_NORMAL: rc = sc; break;
  405.                                 case FZ_BLEND_MULTIPLY: rc = fz_mul255(bc, sc); break;
  406.                                 case FZ_BLEND_SCREEN: rc = fz_screen_byte(bc, sc); break;
  407.                                 case FZ_BLEND_OVERLAY: rc = fz_overlay_byte(bc, sc); break;
  408.                                 case FZ_BLEND_DARKEN: rc = fz_darken_byte(bc, sc); break;
  409.                                 case FZ_BLEND_LIGHTEN: rc = fz_lighten_byte(bc, sc); break;
  410.                                 case FZ_BLEND_COLOR_DODGE: rc = fz_color_dodge_byte(bc, sc); break;
  411.                                 case FZ_BLEND_COLOR_BURN: rc = fz_color_burn_byte(bc, sc); break;
  412.                                 case FZ_BLEND_HARD_LIGHT: rc = fz_hard_light_byte(bc, sc); break;
  413.                                 case FZ_BLEND_SOFT_LIGHT: rc = fz_soft_light_byte(bc, sc); break;
  414.                                 case FZ_BLEND_DIFFERENCE: rc = fz_difference_byte(bc, sc); break;
  415.                                 case FZ_BLEND_EXCLUSION: rc = fz_exclusion_byte(bc, sc); break;
  416.                                 }
  417.                                 rc = fz_mul255(255 - haa, bc) + fz_mul255(fz_mul255(255 - ba, sc), haa) + fz_mul255(baha, rc);
  418.                                 if (rc < 0) rc = 0;
  419.                                 if (rc > 255) rc = 255;
  420.                                 bp[k] = fz_mul255(rc, ra);
  421.                         }
  422.                 }
  423.  
  424.                 sp += n;
  425.                 bp += n;
  426.         }
  427. }
  428.  
  429. static void
  430. fz_blend_nonseparable_nonisolated(byte * restrict bp, byte * restrict sp, int w, int blendmode, byte * restrict hp, int alpha)
  431. {
  432.         while (w--)
  433.         {
  434.                 int ha = *hp++;
  435.                 int haa = fz_mul255(ha, alpha);
  436.                 if (haa != 0)
  437.                 {
  438.                         int sa = sp[3];
  439.                         int ba = bp[3];
  440.                         int baha = fz_mul255(ba, haa);
  441.  
  442.                         /* Calculate result_alpha */
  443.                         int ra = bp[3] = ba - baha + haa;
  444.                         if (ra != 0)
  445.                         {
  446.                                 /* Because we are a non-isolated group, we
  447.                                  * need to 'uncomposite' before we blend
  448.                                  * (recomposite). We assume that normal
  449.                                  * blending has been done inside the group,
  450.                                  * so:     ra.rc = (1-ha).bc + ha.sc
  451.                                  * A bit of rearrangement, and that gives us
  452.                                  * that:   sc = (ra.rc - bc)/ha + bc
  453.                                  * Now, the result of the blend was stored in
  454.                                  * src, so: */
  455.                                 int invha = ha ? 255 * 256 / ha : 0;
  456.  
  457.                                 int rr, rg, rb;
  458.  
  459.                                 /* ugh, division to get non-premul components */
  460.                                 int invsa = sa ? 255 * 256 / sa : 0;
  461.                                 int invba = ba ? 255 * 256 / ba : 0;
  462.  
  463.                                 int sr = (sp[0] * invsa) >> 8;
  464.                                 int sg = (sp[1] * invsa) >> 8;
  465.                                 int sb = (sp[2] * invsa) >> 8;
  466.  
  467.                                 int br = (bp[0] * invba) >> 8;
  468.                                 int bg = (bp[1] * invba) >> 8;
  469.                                 int bb = (bp[2] * invba) >> 8;
  470.  
  471.                                 /* Uncomposite */
  472.                                 sr = (((sr-br)*invha)>>8) + br;
  473.                                 sg = (((sg-bg)*invha)>>8) + bg;
  474.                                 sb = (((sb-bb)*invha)>>8) + bb;
  475.  
  476.                                 switch (blendmode)
  477.                                 {
  478.                                 default:
  479.                                 case FZ_BLEND_HUE:
  480.                                         fz_hue_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb);
  481.                                         break;
  482.                                 case FZ_BLEND_SATURATION:
  483.                                         fz_saturation_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb);
  484.                                         break;
  485.                                 case FZ_BLEND_COLOR:
  486.                                         fz_color_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb);
  487.                                         break;
  488.                                 case FZ_BLEND_LUMINOSITY:
  489.                                         fz_luminosity_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb);
  490.                                         break;
  491.                                 }
  492.  
  493.                                 rr = fz_mul255(255 - haa, bp[0]) + fz_mul255(fz_mul255(255 - ba, sr), haa) + fz_mul255(baha, rr);
  494.                                 rg = fz_mul255(255 - haa, bp[1]) + fz_mul255(fz_mul255(255 - ba, sg), haa) + fz_mul255(baha, rg);
  495.                                 rb = fz_mul255(255 - haa, bp[2]) + fz_mul255(fz_mul255(255 - ba, sb), haa) + fz_mul255(baha, rb);
  496.                                 bp[0] = fz_mul255(ra, rr);
  497.                                 bp[1] = fz_mul255(ra, rg);
  498.                                 bp[2] = fz_mul255(ra, rb);
  499.                         }
  500.                 }
  501.  
  502.                 sp += 4;
  503.                 bp += 4;
  504.         }
  505. }
  506.  
  507. void
  508. fz_blend_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha, int blendmode, int isolated, fz_pixmap *shape)
  509. {
  510.         unsigned char *sp, *dp;
  511.         fz_bbox bbox;
  512.         int x, y, w, h, n;
  513.  
  514.         /* TODO: fix this hack! */
  515.         if (isolated && alpha < 255)
  516.         {
  517.                 sp = src->samples;
  518.                 n = src->w * src->h * src->n;
  519.                 while (n--)
  520.                 {
  521.                         *sp = fz_mul255(*sp, alpha);
  522.                         sp++;
  523.                 }
  524.         }
  525.  
  526.         bbox = fz_bound_pixmap(dst);
  527.         bbox = fz_intersect_bbox(bbox, fz_bound_pixmap(src));
  528.  
  529.         x = bbox.x0;
  530.         y = bbox.y0;
  531.         w = bbox.x1 - bbox.x0;
  532.         h = bbox.y1 - bbox.y0;
  533.  
  534.         n = src->n;
  535.         sp = src->samples + ((y - src->y) * src->w + (x - src->x)) * n;
  536.         dp = dst->samples + ((y - dst->y) * dst->w + (x - dst->x)) * n;
  537.  
  538.         assert(src->n == dst->n);
  539.  
  540.         if (!isolated)
  541.         {
  542.                 unsigned char *hp = shape->samples + (y - shape->y) * shape->w + (x - shape->x);
  543.  
  544.                 while (h--)
  545.                 {
  546.                         if (n == 4 && blendmode >= FZ_BLEND_HUE)
  547.                                 fz_blend_nonseparable_nonisolated(dp, sp, w, blendmode, hp, alpha);
  548.                         else
  549.                                 fz_blend_separable_nonisolated(dp, sp, n, w, blendmode, hp, alpha);
  550.                         sp += src->w * n;
  551.                         dp += dst->w * n;
  552.                         hp += shape->w;
  553.                 }
  554.         }
  555.         else
  556.         {
  557.                 while (h--)
  558.                 {
  559.                         if (n == 4 && blendmode >= FZ_BLEND_HUE)
  560.                                 fz_blend_nonseparable(dp, sp, w, blendmode);
  561.                         else
  562.                                 fz_blend_separable(dp, sp, n, w, blendmode);
  563.                         sp += src->w * n;
  564.                         dp += dst->w * n;
  565.                 }
  566.         }
  567. }
  568.