Home | History | Annotate | Download | only in dib
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "core/include/fxge/fx_ge.h"
      8 #include "core/include/fxcodec/fx_codec.h"
      9 #include "dib_int.h"
     10 
     11 const uint8_t _color_sqrt[256] = {
     12     0x00, 0x03, 0x07, 0x0B, 0x0F, 0x12, 0x16, 0x19, 0x1D, 0x20, 0x23, 0x26,
     13     0x29, 0x2C, 0x2F, 0x32, 0x35, 0x37, 0x3A, 0x3C, 0x3F, 0x41, 0x43, 0x46,
     14     0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x57, 0x59, 0x5B, 0x5C,
     15     0x5E, 0x60, 0x61, 0x63, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D,
     16     0x6E, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
     17     0x7B, 0x7C, 0x7D, 0x7E, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
     18     0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x91,
     19     0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C,
     20     0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5,
     21     0xA6, 0xA7, 0xA7, 0xA8, 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE,
     22     0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB3, 0xB4, 0xB5, 0xB5, 0xB6, 0xB7,
     23     0xB7, 0xB8, 0xB9, 0xBA, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBE, 0xBF,
     24     0xC0, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC4, 0xC5, 0xC6, 0xC6, 0xC7,
     25     0xC7, 0xC8, 0xC9, 0xC9, 0xCA, 0xCB, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCE,
     26     0xCF, 0xD0, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3, 0xD4, 0xD4, 0xD5, 0xD6,
     27     0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD,
     28     0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE2, 0xE3, 0xE4,
     29     0xE4, 0xE5, 0xE5, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA,
     30     0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE, 0xEE, 0xEF, 0xF0, 0xF0, 0xF1,
     31     0xF1, 0xF2, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7,
     32     0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD,
     33     0xFD, 0xFE, 0xFE, 0xFF};
     34 int _BLEND(int blend_mode, int back_color, int src_color) {
     35   switch (blend_mode) {
     36     case FXDIB_BLEND_NORMAL:
     37       return src_color;
     38     case FXDIB_BLEND_MULTIPLY:
     39       return src_color * back_color / 255;
     40     case FXDIB_BLEND_SCREEN:
     41       return src_color + back_color - src_color * back_color / 255;
     42     case FXDIB_BLEND_OVERLAY:
     43       return _BLEND(FXDIB_BLEND_HARDLIGHT, src_color, back_color);
     44     case FXDIB_BLEND_DARKEN:
     45       return src_color < back_color ? src_color : back_color;
     46     case FXDIB_BLEND_LIGHTEN:
     47       return src_color > back_color ? src_color : back_color;
     48     case FXDIB_BLEND_COLORDODGE: {
     49       if (src_color == 255) {
     50         return src_color;
     51       }
     52       int result = back_color * 255 / (255 - src_color);
     53       if (result > 255) {
     54         return 255;
     55       }
     56       return result;
     57     }
     58     case FXDIB_BLEND_COLORBURN: {
     59       if (src_color == 0) {
     60         return src_color;
     61       }
     62       int result = (255 - back_color) * 255 / src_color;
     63       if (result > 255) {
     64         result = 255;
     65       }
     66       return 255 - result;
     67     }
     68     case FXDIB_BLEND_HARDLIGHT:
     69       if (src_color < 128) {
     70         return (src_color * back_color * 2) / 255;
     71       }
     72       return _BLEND(FXDIB_BLEND_SCREEN, back_color, 2 * src_color - 255);
     73     case FXDIB_BLEND_SOFTLIGHT: {
     74       if (src_color < 128) {
     75         return back_color -
     76                (255 - 2 * src_color) * back_color * (255 - back_color) / 255 /
     77                    255;
     78       }
     79       return back_color +
     80              (2 * src_color - 255) * (_color_sqrt[back_color] - back_color) /
     81                  255;
     82     }
     83     case FXDIB_BLEND_DIFFERENCE:
     84       return back_color < src_color ? src_color - back_color
     85                                     : back_color - src_color;
     86     case FXDIB_BLEND_EXCLUSION:
     87       return back_color + src_color - 2 * back_color * src_color / 255;
     88   }
     89   return src_color;
     90 }
     91 struct _RGB {
     92   int red;
     93   int green;
     94   int blue;
     95 };
     96 static inline int _Lum(_RGB color) {
     97   return (color.red * 30 + color.green * 59 + color.blue * 11) / 100;
     98 }
     99 static _RGB _ClipColor(_RGB color) {
    100   int l = _Lum(color);
    101   int n = color.red;
    102   if (color.green < n) {
    103     n = color.green;
    104   }
    105   if (color.blue < n) {
    106     n = color.blue;
    107   }
    108   int x = color.red;
    109   if (color.green > x) {
    110     x = color.green;
    111   }
    112   if (color.blue > x) {
    113     x = color.blue;
    114   }
    115   if (n < 0) {
    116     color.red = l + ((color.red - l) * l / (l - n));
    117     color.green = l + ((color.green - l) * l / (l - n));
    118     color.blue = l + ((color.blue - l) * l / (l - n));
    119   }
    120   if (x > 255) {
    121     color.red = l + ((color.red - l) * (255 - l) / (x - l));
    122     color.green = l + ((color.green - l) * (255 - l) / (x - l));
    123     color.blue = l + ((color.blue - l) * (255 - l) / (x - l));
    124   }
    125   return color;
    126 }
    127 static _RGB _SetLum(_RGB color, int l) {
    128   int d = l - _Lum(color);
    129   color.red += d;
    130   color.green += d;
    131   color.blue += d;
    132   return _ClipColor(color);
    133 }
    134 static int _Sat(_RGB color) {
    135   int n = color.red;
    136   if (color.green < n) {
    137     n = color.green;
    138   }
    139   if (color.blue < n) {
    140     n = color.blue;
    141   }
    142   int x = color.red;
    143   if (color.green > x) {
    144     x = color.green;
    145   }
    146   if (color.blue > x) {
    147     x = color.blue;
    148   }
    149   return x - n;
    150 }
    151 static _RGB _SetSat(_RGB color, int s) {
    152   int* max = &color.red;
    153   int* mid = &color.red;
    154   int* min = &color.red;
    155   if (color.green > *max) {
    156     max = &color.green;
    157   }
    158   if (color.blue > *max) {
    159     max = &color.blue;
    160   }
    161   if (color.green < *min) {
    162     min = &color.green;
    163   }
    164   if (color.blue < *min) {
    165     min = &color.blue;
    166   }
    167   if (*max == *min) {
    168     color.red = 0;
    169     color.green = 0;
    170     color.blue = 0;
    171     return color;
    172   }
    173   if (max == &color.red) {
    174     if (min == &color.green) {
    175       mid = &color.blue;
    176     } else {
    177       mid = &color.green;
    178     }
    179   } else if (max == &color.green) {
    180     if (min == &color.red) {
    181       mid = &color.blue;
    182     } else {
    183       mid = &color.red;
    184     }
    185   } else {
    186     if (min == &color.green) {
    187       mid = &color.red;
    188     } else {
    189       mid = &color.green;
    190     }
    191   }
    192   if (*max > *min) {
    193     *mid = (*mid - *min) * s / (*max - *min);
    194     *max = s;
    195     *min = 0;
    196   }
    197   return color;
    198 }
    199 void _RGB_Blend(int blend_mode,
    200                 const uint8_t* src_scan,
    201                 uint8_t* dest_scan,
    202                 int results[3]) {
    203   _RGB src, back, result;
    204   src.red = src_scan[2];
    205   src.green = src_scan[1];
    206   src.blue = src_scan[0];
    207   back.red = dest_scan[2];
    208   back.green = dest_scan[1];
    209   back.blue = dest_scan[0];
    210   switch (blend_mode) {
    211     case FXDIB_BLEND_HUE:
    212       result = _SetLum(_SetSat(src, _Sat(back)), _Lum(back));
    213       break;
    214     case FXDIB_BLEND_SATURATION:
    215       result = _SetLum(_SetSat(back, _Sat(src)), _Lum(back));
    216       break;
    217     case FXDIB_BLEND_COLOR:
    218       result = _SetLum(src, _Lum(back));
    219       break;
    220     case FXDIB_BLEND_LUMINOSITY:
    221       result = _SetLum(back, _Lum(src));
    222       break;
    223   }
    224   results[0] = result.blue;
    225   results[1] = result.green;
    226   results[2] = result.red;
    227 }
    228 inline void _CompositeRow_Argb2Mask(uint8_t* dest_scan,
    229                                     const uint8_t* src_scan,
    230                                     int pixel_count,
    231                                     const uint8_t* clip_scan) {
    232   src_scan += 3;
    233   for (int col = 0; col < pixel_count; col++) {
    234     int src_alpha = *src_scan;
    235     if (clip_scan) {
    236       src_alpha = clip_scan[col] * src_alpha / 255;
    237     }
    238     uint8_t back_alpha = *dest_scan;
    239     if (!back_alpha) {
    240       *dest_scan = src_alpha;
    241     } else if (src_alpha) {
    242       *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
    243     }
    244     dest_scan++;
    245     src_scan += 4;
    246   }
    247 }
    248 void _CompositeRow_Rgba2Mask(uint8_t* dest_scan,
    249                              const uint8_t* src_alpha_scan,
    250                              int pixel_count,
    251                              const uint8_t* clip_scan) {
    252   for (int col = 0; col < pixel_count; col++) {
    253     int src_alpha = *src_alpha_scan++;
    254     if (clip_scan) {
    255       src_alpha = clip_scan[col] * src_alpha / 255;
    256     }
    257     uint8_t back_alpha = *dest_scan;
    258     if (!back_alpha) {
    259       *dest_scan = src_alpha;
    260     } else if (src_alpha) {
    261       *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
    262     }
    263     dest_scan++;
    264   }
    265 }
    266 void _CompositeRow_Rgb2Mask(uint8_t* dest_scan,
    267                             const uint8_t* src_scan,
    268                             int width,
    269                             const uint8_t* clip_scan) {
    270   if (clip_scan) {
    271     for (int i = 0; i < width; i++) {
    272       *dest_scan = FXDIB_ALPHA_UNION(*dest_scan, *clip_scan);
    273       dest_scan++;
    274       clip_scan++;
    275     }
    276   } else {
    277     FXSYS_memset(dest_scan, 0xff, width);
    278   }
    279 }
    280 void _CompositeRow_Argb2Graya(uint8_t* dest_scan,
    281                               const uint8_t* src_scan,
    282                               int pixel_count,
    283                               int blend_type,
    284                               const uint8_t* clip_scan,
    285                               const uint8_t* src_alpha_scan,
    286                               uint8_t* dst_alpha_scan,
    287                               void* pIccTransform) {
    288   ICodec_IccModule* pIccModule = NULL;
    289   if (pIccTransform) {
    290     pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
    291   }
    292   if (blend_type) {
    293     FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
    294     int blended_color;
    295     if (src_alpha_scan) {
    296       for (int col = 0; col < pixel_count; col++) {
    297         uint8_t back_alpha = *dst_alpha_scan;
    298         if (back_alpha == 0) {
    299           int src_alpha = *src_alpha_scan++;
    300           if (clip_scan) {
    301             src_alpha = clip_scan[col] * src_alpha / 255;
    302           }
    303           if (src_alpha) {
    304             if (pIccTransform) {
    305               pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan,
    306                                             1);
    307             } else {
    308               *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    309             }
    310             *dst_alpha_scan = src_alpha;
    311           }
    312           dest_scan++;
    313           dst_alpha_scan++;
    314           src_scan += 3;
    315           continue;
    316         }
    317         uint8_t src_alpha = *src_alpha_scan++;
    318         if (clip_scan) {
    319           src_alpha = clip_scan[col] * src_alpha / 255;
    320         }
    321         if (src_alpha == 0) {
    322           dest_scan++;
    323           dst_alpha_scan++;
    324           src_scan += 3;
    325           continue;
    326         }
    327         *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
    328         int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
    329         uint8_t gray;
    330         if (pIccTransform) {
    331           pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    332         } else {
    333           gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    334         }
    335         if (bNonseparableBlend) {
    336           blended_color =
    337               blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
    338         }
    339         gray = bNonseparableBlend ? blended_color
    340                                   : _BLEND(blend_type, *dest_scan, gray);
    341         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
    342         dest_scan++;
    343         dst_alpha_scan++;
    344         src_scan += 3;
    345       }
    346     } else
    347       for (int col = 0; col < pixel_count; col++) {
    348         uint8_t back_alpha = *dst_alpha_scan;
    349         if (back_alpha == 0) {
    350           int src_alpha = src_scan[3];
    351           if (clip_scan) {
    352             src_alpha = clip_scan[col] * src_alpha / 255;
    353           }
    354           if (src_alpha) {
    355             if (pIccTransform) {
    356               pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan,
    357                                             1);
    358             } else {
    359               *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    360             }
    361             *dst_alpha_scan = src_alpha;
    362           }
    363           dest_scan++;
    364           dst_alpha_scan++;
    365           src_scan += 4;
    366           continue;
    367         }
    368         uint8_t src_alpha = src_scan[3];
    369         if (clip_scan) {
    370           src_alpha = clip_scan[col] * src_alpha / 255;
    371         }
    372         if (src_alpha == 0) {
    373           dest_scan++;
    374           dst_alpha_scan++;
    375           src_scan += 4;
    376           continue;
    377         }
    378         *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
    379         int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
    380         uint8_t gray;
    381         if (pIccTransform) {
    382           pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    383         } else {
    384           gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    385         }
    386         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
    387         dest_scan++;
    388         dst_alpha_scan++;
    389         src_scan += 4;
    390       }
    391     return;
    392   }
    393   if (src_alpha_scan) {
    394     for (int col = 0; col < pixel_count; col++) {
    395       uint8_t back_alpha = *dst_alpha_scan;
    396       if (back_alpha == 0) {
    397         int src_alpha = *src_alpha_scan++;
    398         if (clip_scan) {
    399           src_alpha = clip_scan[col] * src_alpha / 255;
    400         }
    401         if (src_alpha) {
    402           if (pIccTransform) {
    403             pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan,
    404                                           1);
    405           } else {
    406             *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    407           }
    408           *dst_alpha_scan = src_alpha;
    409         }
    410         dest_scan++;
    411         dst_alpha_scan++;
    412         src_scan += 3;
    413         continue;
    414       }
    415       uint8_t src_alpha = *src_alpha_scan++;
    416       if (clip_scan) {
    417         src_alpha = clip_scan[col] * src_alpha / 255;
    418       }
    419       if (src_alpha == 0) {
    420         dest_scan++;
    421         dst_alpha_scan++;
    422         src_scan += 3;
    423         continue;
    424       }
    425       *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
    426       int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
    427       uint8_t gray;
    428       if (pIccTransform) {
    429         pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    430       } else {
    431         gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    432       }
    433       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
    434       dest_scan++;
    435       dst_alpha_scan++;
    436       src_scan += 3;
    437     }
    438   } else
    439     for (int col = 0; col < pixel_count; col++) {
    440       uint8_t back_alpha = *dst_alpha_scan;
    441       if (back_alpha == 0) {
    442         int src_alpha = src_scan[3];
    443         if (clip_scan) {
    444           src_alpha = clip_scan[col] * src_alpha / 255;
    445         }
    446         if (src_alpha) {
    447           if (pIccTransform) {
    448             pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan,
    449                                           1);
    450           } else {
    451             *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    452           }
    453           *dst_alpha_scan = src_alpha;
    454         }
    455         dest_scan++;
    456         dst_alpha_scan++;
    457         src_scan += 4;
    458         continue;
    459       }
    460       uint8_t src_alpha = src_scan[3];
    461       if (clip_scan) {
    462         src_alpha = clip_scan[col] * src_alpha / 255;
    463       }
    464       if (src_alpha == 0) {
    465         dest_scan++;
    466         dst_alpha_scan++;
    467         src_scan += 4;
    468         continue;
    469       }
    470       *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
    471       int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
    472       uint8_t gray;
    473       if (pIccTransform) {
    474         pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    475       } else {
    476         gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    477       }
    478       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
    479       dest_scan++;
    480       dst_alpha_scan++;
    481       src_scan += 4;
    482     }
    483 }
    484 inline void _CompositeRow_Argb2Gray(uint8_t* dest_scan,
    485                                     const uint8_t* src_scan,
    486                                     int pixel_count,
    487                                     int blend_type,
    488                                     const uint8_t* clip_scan,
    489                                     const uint8_t* src_alpha_scan,
    490                                     void* pIccTransform) {
    491   ICodec_IccModule* pIccModule = NULL;
    492   uint8_t gray;
    493   if (pIccTransform) {
    494     pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
    495   }
    496   if (blend_type) {
    497     FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
    498     int blended_color;
    499     if (src_alpha_scan) {
    500       for (int col = 0; col < pixel_count; col++) {
    501         int src_alpha = *src_alpha_scan++;
    502         if (clip_scan) {
    503           src_alpha = clip_scan[col] * src_alpha / 255;
    504         }
    505         if (src_alpha) {
    506           if (pIccTransform) {
    507             pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    508           } else {
    509             gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    510           }
    511           if (bNonseparableBlend) {
    512             blended_color =
    513                 blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
    514           }
    515           gray = bNonseparableBlend ? blended_color
    516                                     : _BLEND(blend_type, *dest_scan, gray);
    517           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
    518         }
    519         dest_scan++;
    520         src_scan += 3;
    521       }
    522     } else
    523       for (int col = 0; col < pixel_count; col++) {
    524         int src_alpha = src_scan[3];
    525         if (clip_scan) {
    526           src_alpha = clip_scan[col] * src_alpha / 255;
    527         }
    528         if (src_alpha) {
    529           if (pIccTransform) {
    530             pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    531           } else {
    532             gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    533           }
    534           if (bNonseparableBlend) {
    535             blended_color =
    536                 blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
    537           }
    538           gray = bNonseparableBlend ? blended_color
    539                                     : _BLEND(blend_type, *dest_scan, gray);
    540           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
    541         }
    542         dest_scan++;
    543         src_scan += 4;
    544       }
    545     return;
    546   }
    547   if (src_alpha_scan) {
    548     for (int col = 0; col < pixel_count; col++) {
    549       int src_alpha = *src_alpha_scan++;
    550       if (clip_scan) {
    551         src_alpha = clip_scan[col] * src_alpha / 255;
    552       }
    553       if (src_alpha) {
    554         if (pIccTransform) {
    555           pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    556         } else {
    557           gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    558         }
    559         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
    560       }
    561       dest_scan++;
    562       src_scan += 3;
    563     }
    564   } else
    565     for (int col = 0; col < pixel_count; col++) {
    566       int src_alpha = src_scan[3];
    567       if (clip_scan) {
    568         src_alpha = clip_scan[col] * src_alpha / 255;
    569       }
    570       if (src_alpha) {
    571         if (pIccTransform) {
    572           pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    573         } else {
    574           gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    575         }
    576         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
    577       }
    578       dest_scan++;
    579       src_scan += 4;
    580     }
    581 }
    582 inline void _CompositeRow_Rgb2Gray(uint8_t* dest_scan,
    583                                    const uint8_t* src_scan,
    584                                    int src_Bpp,
    585                                    int pixel_count,
    586                                    int blend_type,
    587                                    const uint8_t* clip_scan,
    588                                    void* pIccTransform) {
    589   ICodec_IccModule* pIccModule = NULL;
    590   uint8_t gray;
    591   if (pIccTransform) {
    592     pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
    593   }
    594   if (blend_type) {
    595     FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
    596     int blended_color;
    597     for (int col = 0; col < pixel_count; col++) {
    598       if (pIccTransform) {
    599         pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    600       } else {
    601         gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    602       }
    603       if (bNonseparableBlend) {
    604         blended_color =
    605             blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
    606       }
    607       gray = bNonseparableBlend ? blended_color
    608                                 : _BLEND(blend_type, *dest_scan, gray);
    609       if (clip_scan && clip_scan[col] < 255) {
    610         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
    611       } else {
    612         *dest_scan = gray;
    613       }
    614       dest_scan++;
    615       src_scan += src_Bpp;
    616     }
    617     return;
    618   }
    619   for (int col = 0; col < pixel_count; col++) {
    620     if (pIccTransform) {
    621       pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    622     } else {
    623       gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    624     }
    625     if (clip_scan && clip_scan[col] < 255) {
    626       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
    627     } else {
    628       *dest_scan = gray;
    629     }
    630     dest_scan++;
    631     src_scan += src_Bpp;
    632   }
    633 }
    634 void _CompositeRow_Rgb2Graya(uint8_t* dest_scan,
    635                              const uint8_t* src_scan,
    636                              int src_Bpp,
    637                              int pixel_count,
    638                              int blend_type,
    639                              const uint8_t* clip_scan,
    640                              uint8_t* dest_alpha_scan,
    641                              void* pIccTransform) {
    642   ICodec_IccModule* pIccModule = NULL;
    643   if (pIccTransform) {
    644     pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
    645   }
    646   if (blend_type) {
    647     int blended_color;
    648     FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
    649     for (int col = 0; col < pixel_count; col++) {
    650       int back_alpha = *dest_alpha_scan;
    651       if (back_alpha == 0) {
    652         if (pIccTransform) {
    653           pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
    654         } else {
    655           *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    656         }
    657         dest_scan++;
    658         dest_alpha_scan++;
    659         src_scan += src_Bpp;
    660         continue;
    661       }
    662       int src_alpha = 255;
    663       if (clip_scan) {
    664         src_alpha = clip_scan[col];
    665       }
    666       if (src_alpha == 0) {
    667         dest_scan++;
    668         dest_alpha_scan++;
    669         src_scan += src_Bpp;
    670         continue;
    671       }
    672       uint8_t dest_alpha =
    673           back_alpha + src_alpha - back_alpha * src_alpha / 255;
    674       *dest_alpha_scan++ = dest_alpha;
    675       int alpha_ratio = src_alpha * 255 / dest_alpha;
    676       uint8_t gray;
    677       if (pIccTransform) {
    678         pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    679       } else {
    680         gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    681       }
    682       if (bNonseparableBlend) {
    683         blended_color =
    684             blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
    685       }
    686       gray = bNonseparableBlend ? blended_color
    687                                 : _BLEND(blend_type, *dest_scan, gray);
    688       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
    689       dest_scan++;
    690       src_scan += src_Bpp;
    691     }
    692     return;
    693   }
    694   for (int col = 0; col < pixel_count; col++) {
    695     int src_alpha = 255;
    696     if (clip_scan) {
    697       src_alpha = clip_scan[col];
    698     }
    699     if (src_alpha == 255) {
    700       if (pIccTransform) {
    701         pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
    702       } else {
    703         *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    704       }
    705       dest_scan++;
    706       *dest_alpha_scan++ = 255;
    707       src_scan += src_Bpp;
    708       continue;
    709     }
    710     if (src_alpha == 0) {
    711       dest_scan++;
    712       dest_alpha_scan++;
    713       src_scan += src_Bpp;
    714       continue;
    715     }
    716     int back_alpha = *dest_alpha_scan;
    717     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
    718     *dest_alpha_scan++ = dest_alpha;
    719     int alpha_ratio = src_alpha * 255 / dest_alpha;
    720     uint8_t gray;
    721     if (pIccTransform) {
    722       pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
    723     } else {
    724       gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
    725     }
    726     *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
    727     dest_scan++;
    728     src_scan += src_Bpp;
    729   }
    730 }
    731 void _CompositeRow_Argb2Argb(uint8_t* dest_scan,
    732                              const uint8_t* src_scan,
    733                              int pixel_count,
    734                              int blend_type,
    735                              const uint8_t* clip_scan,
    736                              uint8_t* dest_alpha_scan,
    737                              const uint8_t* src_alpha_scan) {
    738   int blended_colors[3];
    739   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
    740   if (!dest_alpha_scan) {
    741     if (!src_alpha_scan) {
    742       uint8_t back_alpha = 0;
    743       for (int col = 0; col < pixel_count; col++) {
    744         back_alpha = dest_scan[3];
    745         if (back_alpha == 0) {
    746           if (clip_scan) {
    747             int src_alpha = clip_scan[col] * src_scan[3] / 255;
    748             FXARGB_SETDIB(dest_scan, (FXARGB_GETDIB(src_scan) & 0xffffff) |
    749                                          (src_alpha << 24));
    750           } else {
    751             FXARGB_COPY(dest_scan, src_scan);
    752           }
    753           dest_scan += 4;
    754           src_scan += 4;
    755           continue;
    756         }
    757         uint8_t src_alpha;
    758         if (clip_scan) {
    759           src_alpha = clip_scan[col] * src_scan[3] / 255;
    760         } else {
    761           src_alpha = src_scan[3];
    762         }
    763         if (src_alpha == 0) {
    764           dest_scan += 4;
    765           src_scan += 4;
    766           continue;
    767         }
    768         uint8_t dest_alpha =
    769             back_alpha + src_alpha - back_alpha * src_alpha / 255;
    770         dest_scan[3] = dest_alpha;
    771         int alpha_ratio = src_alpha * 255 / dest_alpha;
    772         if (bNonseparableBlend) {
    773           _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
    774         }
    775         for (int color = 0; color < 3; color++) {
    776           if (blend_type) {
    777             int blended = bNonseparableBlend
    778                               ? blended_colors[color]
    779                               : _BLEND(blend_type, *dest_scan, *src_scan);
    780             blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
    781             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
    782           } else {
    783             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
    784           }
    785           dest_scan++;
    786           src_scan++;
    787         }
    788         dest_scan++;
    789         src_scan++;
    790       }
    791     } else {
    792       for (int col = 0; col < pixel_count; col++) {
    793         uint8_t back_alpha = dest_scan[3];
    794         if (back_alpha == 0) {
    795           if (clip_scan) {
    796             int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
    797             FXARGB_SETDIB(dest_scan, FXARGB_MAKE((src_alpha << 24), src_scan[2],
    798                                                  src_scan[1], *src_scan));
    799           } else {
    800             FXARGB_SETDIB(dest_scan,
    801                           FXARGB_MAKE((*src_alpha_scan << 24), src_scan[2],
    802                                       src_scan[1], *src_scan));
    803           }
    804           dest_scan += 4;
    805           src_scan += 3;
    806           src_alpha_scan++;
    807           continue;
    808         }
    809         uint8_t src_alpha;
    810         if (clip_scan) {
    811           src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
    812         } else {
    813           src_alpha = *src_alpha_scan++;
    814         }
    815         if (src_alpha == 0) {
    816           dest_scan += 4;
    817           src_scan += 3;
    818           continue;
    819         }
    820         uint8_t dest_alpha =
    821             back_alpha + src_alpha - back_alpha * src_alpha / 255;
    822         dest_scan[3] = dest_alpha;
    823         int alpha_ratio = src_alpha * 255 / dest_alpha;
    824         if (bNonseparableBlend) {
    825           _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
    826         }
    827         for (int color = 0; color < 3; color++) {
    828           if (blend_type) {
    829             int blended = bNonseparableBlend
    830                               ? blended_colors[color]
    831                               : _BLEND(blend_type, *dest_scan, *src_scan);
    832             blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
    833             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
    834           } else {
    835             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
    836           }
    837           dest_scan++;
    838           src_scan++;
    839         }
    840         dest_scan++;
    841       }
    842     }
    843   } else {
    844     if (src_alpha_scan) {
    845       for (int col = 0; col < pixel_count; col++) {
    846         uint8_t back_alpha = *dest_alpha_scan;
    847         if (back_alpha == 0) {
    848           if (clip_scan) {
    849             int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
    850             *dest_alpha_scan = src_alpha;
    851             *dest_scan++ = *src_scan++;
    852             *dest_scan++ = *src_scan++;
    853             *dest_scan++ = *src_scan++;
    854           } else {
    855             *dest_alpha_scan = *src_alpha_scan;
    856             *dest_scan++ = *src_scan++;
    857             *dest_scan++ = *src_scan++;
    858             *dest_scan++ = *src_scan++;
    859           }
    860           dest_alpha_scan++;
    861           src_alpha_scan++;
    862           continue;
    863         }
    864         uint8_t src_alpha;
    865         if (clip_scan) {
    866           src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
    867         } else {
    868           src_alpha = *src_alpha_scan++;
    869         }
    870         if (src_alpha == 0) {
    871           dest_scan += 3;
    872           src_scan += 3;
    873           dest_alpha_scan++;
    874           continue;
    875         }
    876         uint8_t dest_alpha =
    877             back_alpha + src_alpha - back_alpha * src_alpha / 255;
    878         *dest_alpha_scan++ = dest_alpha;
    879         int alpha_ratio = src_alpha * 255 / dest_alpha;
    880         if (bNonseparableBlend) {
    881           _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
    882         }
    883         for (int color = 0; color < 3; color++) {
    884           if (blend_type) {
    885             int blended = bNonseparableBlend
    886                               ? blended_colors[color]
    887                               : _BLEND(blend_type, *dest_scan, *src_scan);
    888             blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
    889             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
    890           } else {
    891             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
    892           }
    893           dest_scan++;
    894           src_scan++;
    895         }
    896       }
    897     } else {
    898       for (int col = 0; col < pixel_count; col++) {
    899         uint8_t back_alpha = *dest_alpha_scan;
    900         if (back_alpha == 0) {
    901           if (clip_scan) {
    902             int src_alpha = clip_scan[col] * src_scan[3] / 255;
    903             *dest_alpha_scan = src_alpha;
    904             *dest_scan++ = *src_scan++;
    905             *dest_scan++ = *src_scan++;
    906             *dest_scan++ = *src_scan++;
    907           } else {
    908             *dest_alpha_scan = src_scan[3];
    909             *dest_scan++ = *src_scan++;
    910             *dest_scan++ = *src_scan++;
    911             *dest_scan++ = *src_scan++;
    912           }
    913           dest_alpha_scan++;
    914           src_scan++;
    915           continue;
    916         }
    917         uint8_t src_alpha;
    918         if (clip_scan) {
    919           src_alpha = clip_scan[col] * src_scan[3] / 255;
    920         } else {
    921           src_alpha = src_scan[3];
    922         }
    923         if (src_alpha == 0) {
    924           dest_scan += 3;
    925           src_scan += 4;
    926           dest_alpha_scan++;
    927           continue;
    928         }
    929         uint8_t dest_alpha =
    930             back_alpha + src_alpha - back_alpha * src_alpha / 255;
    931         *dest_alpha_scan++ = dest_alpha;
    932         int alpha_ratio = src_alpha * 255 / dest_alpha;
    933         if (bNonseparableBlend) {
    934           _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
    935         }
    936         for (int color = 0; color < 3; color++) {
    937           if (blend_type) {
    938             int blended = bNonseparableBlend
    939                               ? blended_colors[color]
    940                               : _BLEND(blend_type, *dest_scan, *src_scan);
    941             blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
    942             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
    943           } else {
    944             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
    945           }
    946           dest_scan++;
    947           src_scan++;
    948         }
    949         src_scan++;
    950       }
    951     }
    952   }
    953 }
    954 void _CompositeRow_Rgb2Argb_Blend_NoClip(uint8_t* dest_scan,
    955                                          const uint8_t* src_scan,
    956                                          int width,
    957                                          int blend_type,
    958                                          int src_Bpp,
    959                                          uint8_t* dest_alpha_scan) {
    960   int blended_colors[3];
    961   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
    962   int src_gap = src_Bpp - 3;
    963   if (dest_alpha_scan) {
    964     for (int col = 0; col < width; col++) {
    965       uint8_t back_alpha = *dest_alpha_scan;
    966       if (back_alpha == 0) {
    967         *dest_scan++ = *src_scan++;
    968         *dest_scan++ = *src_scan++;
    969         *dest_scan++ = *src_scan++;
    970         *dest_alpha_scan++ = 0xff;
    971         src_scan += src_gap;
    972         continue;
    973       }
    974       *dest_alpha_scan++ = 0xff;
    975       if (bNonseparableBlend) {
    976         _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
    977       }
    978       for (int color = 0; color < 3; color++) {
    979         int src_color = *src_scan;
    980         int blended = bNonseparableBlend
    981                           ? blended_colors[color]
    982                           : _BLEND(blend_type, *dest_scan, src_color);
    983         *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
    984         dest_scan++;
    985         src_scan++;
    986       }
    987       src_scan += src_gap;
    988     }
    989   } else {
    990     for (int col = 0; col < width; col++) {
    991       uint8_t back_alpha = dest_scan[3];
    992       if (back_alpha == 0) {
    993         if (src_Bpp == 4) {
    994           FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
    995         } else {
    996           FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1],
    997                                                src_scan[0]));
    998         }
    999         dest_scan += 4;
   1000         src_scan += src_Bpp;
   1001         continue;
   1002       }
   1003       dest_scan[3] = 0xff;
   1004       if (bNonseparableBlend) {
   1005         _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   1006       }
   1007       for (int color = 0; color < 3; color++) {
   1008         int src_color = *src_scan;
   1009         int blended = bNonseparableBlend
   1010                           ? blended_colors[color]
   1011                           : _BLEND(blend_type, *dest_scan, src_color);
   1012         *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
   1013         dest_scan++;
   1014         src_scan++;
   1015       }
   1016       dest_scan++;
   1017       src_scan += src_gap;
   1018     }
   1019   }
   1020 }
   1021 inline void _CompositeRow_Rgb2Argb_Blend_Clip(uint8_t* dest_scan,
   1022                                               const uint8_t* src_scan,
   1023                                               int width,
   1024                                               int blend_type,
   1025                                               int src_Bpp,
   1026                                               const uint8_t* clip_scan,
   1027                                               uint8_t* dest_alpha_scan) {
   1028   int blended_colors[3];
   1029   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   1030   int src_gap = src_Bpp - 3;
   1031   if (dest_alpha_scan) {
   1032     for (int col = 0; col < width; col++) {
   1033       int src_alpha = *clip_scan++;
   1034       uint8_t back_alpha = *dest_alpha_scan;
   1035       if (back_alpha == 0) {
   1036         *dest_scan++ = *src_scan++;
   1037         *dest_scan++ = *src_scan++;
   1038         *dest_scan++ = *src_scan++;
   1039         src_scan += src_gap;
   1040         dest_alpha_scan++;
   1041         continue;
   1042       }
   1043       if (src_alpha == 0) {
   1044         dest_scan += 3;
   1045         dest_alpha_scan++;
   1046         src_scan += src_Bpp;
   1047         continue;
   1048       }
   1049       uint8_t dest_alpha =
   1050           back_alpha + src_alpha - back_alpha * src_alpha / 255;
   1051       *dest_alpha_scan++ = dest_alpha;
   1052       int alpha_ratio = src_alpha * 255 / dest_alpha;
   1053       if (bNonseparableBlend) {
   1054         _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   1055       }
   1056       for (int color = 0; color < 3; color++) {
   1057         int src_color = *src_scan;
   1058         int blended = bNonseparableBlend
   1059                           ? blended_colors[color]
   1060                           : _BLEND(blend_type, *dest_scan, src_color);
   1061         blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
   1062         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   1063         dest_scan++;
   1064         src_scan++;
   1065       }
   1066       src_scan += src_gap;
   1067     }
   1068   } else {
   1069     for (int col = 0; col < width; col++) {
   1070       int src_alpha = *clip_scan++;
   1071       uint8_t back_alpha = dest_scan[3];
   1072       if (back_alpha == 0) {
   1073         *dest_scan++ = *src_scan++;
   1074         *dest_scan++ = *src_scan++;
   1075         *dest_scan++ = *src_scan++;
   1076         src_scan += src_gap;
   1077         dest_scan++;
   1078         continue;
   1079       }
   1080       if (src_alpha == 0) {
   1081         dest_scan += 4;
   1082         src_scan += src_Bpp;
   1083         continue;
   1084       }
   1085       uint8_t dest_alpha =
   1086           back_alpha + src_alpha - back_alpha * src_alpha / 255;
   1087       dest_scan[3] = dest_alpha;
   1088       int alpha_ratio = src_alpha * 255 / dest_alpha;
   1089       if (bNonseparableBlend) {
   1090         _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   1091       }
   1092       for (int color = 0; color < 3; color++) {
   1093         int src_color = *src_scan;
   1094         int blended = bNonseparableBlend
   1095                           ? blended_colors[color]
   1096                           : _BLEND(blend_type, *dest_scan, src_color);
   1097         blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
   1098         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   1099         dest_scan++;
   1100         src_scan++;
   1101       }
   1102       dest_scan++;
   1103       src_scan += src_gap;
   1104     }
   1105   }
   1106 }
   1107 inline void _CompositeRow_Rgb2Argb_NoBlend_Clip(uint8_t* dest_scan,
   1108                                                 const uint8_t* src_scan,
   1109                                                 int width,
   1110                                                 int src_Bpp,
   1111                                                 const uint8_t* clip_scan,
   1112                                                 uint8_t* dest_alpha_scan) {
   1113   int src_gap = src_Bpp - 3;
   1114   if (dest_alpha_scan) {
   1115     for (int col = 0; col < width; col++) {
   1116       int src_alpha = clip_scan[col];
   1117       if (src_alpha == 255) {
   1118         *dest_scan++ = *src_scan++;
   1119         *dest_scan++ = *src_scan++;
   1120         *dest_scan++ = *src_scan++;
   1121         *dest_alpha_scan++ = 255;
   1122         src_scan += src_gap;
   1123         continue;
   1124       }
   1125       if (src_alpha == 0) {
   1126         dest_scan += 3;
   1127         dest_alpha_scan++;
   1128         src_scan += src_Bpp;
   1129         continue;
   1130       }
   1131       int back_alpha = *dest_alpha_scan;
   1132       uint8_t dest_alpha =
   1133           back_alpha + src_alpha - back_alpha * src_alpha / 255;
   1134       *dest_alpha_scan++ = dest_alpha;
   1135       int alpha_ratio = src_alpha * 255 / dest_alpha;
   1136       for (int color = 0; color < 3; color++) {
   1137         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
   1138         dest_scan++;
   1139         src_scan++;
   1140       }
   1141       src_scan += src_gap;
   1142     }
   1143   } else {
   1144     for (int col = 0; col < width; col++) {
   1145       int src_alpha = clip_scan[col];
   1146       if (src_alpha == 255) {
   1147         *dest_scan++ = *src_scan++;
   1148         *dest_scan++ = *src_scan++;
   1149         *dest_scan++ = *src_scan++;
   1150         *dest_scan++ = 255;
   1151         src_scan += src_gap;
   1152         continue;
   1153       }
   1154       if (src_alpha == 0) {
   1155         dest_scan += 4;
   1156         src_scan += src_Bpp;
   1157         continue;
   1158       }
   1159       int back_alpha = dest_scan[3];
   1160       uint8_t dest_alpha =
   1161           back_alpha + src_alpha - back_alpha * src_alpha / 255;
   1162       dest_scan[3] = dest_alpha;
   1163       int alpha_ratio = src_alpha * 255 / dest_alpha;
   1164       for (int color = 0; color < 3; color++) {
   1165         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
   1166         dest_scan++;
   1167         src_scan++;
   1168       }
   1169       dest_scan++;
   1170       src_scan += src_gap;
   1171     }
   1172   }
   1173 }
   1174 inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip(uint8_t* dest_scan,
   1175                                                   const uint8_t* src_scan,
   1176                                                   int width,
   1177                                                   int src_Bpp,
   1178                                                   uint8_t* dest_alpha_scan) {
   1179   if (dest_alpha_scan) {
   1180     int src_gap = src_Bpp - 3;
   1181     for (int col = 0; col < width; col++) {
   1182       *dest_scan++ = *src_scan++;
   1183       *dest_scan++ = *src_scan++;
   1184       *dest_scan++ = *src_scan++;
   1185       *dest_alpha_scan++ = 0xff;
   1186       src_scan += src_gap;
   1187     }
   1188   } else {
   1189     for (int col = 0; col < width; col++) {
   1190       if (src_Bpp == 4) {
   1191         FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
   1192       } else {
   1193         FXARGB_SETDIB(dest_scan,
   1194                       FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
   1195       }
   1196       dest_scan += 4;
   1197       src_scan += src_Bpp;
   1198     }
   1199   }
   1200 }
   1201 inline void _CompositeRow_Argb2Rgb_Blend(uint8_t* dest_scan,
   1202                                          const uint8_t* src_scan,
   1203                                          int width,
   1204                                          int blend_type,
   1205                                          int dest_Bpp,
   1206                                          const uint8_t* clip_scan,
   1207                                          const uint8_t* src_alpha_scan) {
   1208   int blended_colors[3];
   1209   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   1210   int dest_gap = dest_Bpp - 3;
   1211   if (src_alpha_scan) {
   1212     for (int col = 0; col < width; col++) {
   1213       uint8_t src_alpha;
   1214       if (clip_scan) {
   1215         src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
   1216       } else {
   1217         src_alpha = *src_alpha_scan++;
   1218       }
   1219       if (src_alpha == 0) {
   1220         dest_scan += dest_Bpp;
   1221         src_scan += 3;
   1222         continue;
   1223       }
   1224       if (bNonseparableBlend) {
   1225         _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   1226       }
   1227       for (int color = 0; color < 3; color++) {
   1228         int back_color = *dest_scan;
   1229         int blended = bNonseparableBlend
   1230                           ? blended_colors[color]
   1231                           : _BLEND(blend_type, back_color, *src_scan);
   1232         *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
   1233         dest_scan++;
   1234         src_scan++;
   1235       }
   1236       dest_scan += dest_gap;
   1237     }
   1238   } else {
   1239     for (int col = 0; col < width; col++) {
   1240       uint8_t src_alpha;
   1241       if (clip_scan) {
   1242         src_alpha = src_scan[3] * (*clip_scan++) / 255;
   1243       } else {
   1244         src_alpha = src_scan[3];
   1245       }
   1246       if (src_alpha == 0) {
   1247         dest_scan += dest_Bpp;
   1248         src_scan += 4;
   1249         continue;
   1250       }
   1251       if (bNonseparableBlend) {
   1252         _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   1253       }
   1254       for (int color = 0; color < 3; color++) {
   1255         int back_color = *dest_scan;
   1256         int blended = bNonseparableBlend
   1257                           ? blended_colors[color]
   1258                           : _BLEND(blend_type, back_color, *src_scan);
   1259         *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
   1260         dest_scan++;
   1261         src_scan++;
   1262       }
   1263       dest_scan += dest_gap;
   1264       src_scan++;
   1265     }
   1266   }
   1267 }
   1268 inline void _CompositeRow_Argb2Rgb_NoBlend(uint8_t* dest_scan,
   1269                                            const uint8_t* src_scan,
   1270                                            int width,
   1271                                            int dest_Bpp,
   1272                                            const uint8_t* clip_scan,
   1273                                            const uint8_t* src_alpha_scan) {
   1274   int dest_gap = dest_Bpp - 3;
   1275   if (src_alpha_scan) {
   1276     for (int col = 0; col < width; col++) {
   1277       uint8_t src_alpha;
   1278       if (clip_scan) {
   1279         src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
   1280       } else {
   1281         src_alpha = *src_alpha_scan++;
   1282       }
   1283       if (src_alpha == 255) {
   1284         *dest_scan++ = *src_scan++;
   1285         *dest_scan++ = *src_scan++;
   1286         *dest_scan++ = *src_scan++;
   1287         dest_scan += dest_gap;
   1288         continue;
   1289       }
   1290       if (src_alpha == 0) {
   1291         dest_scan += dest_Bpp;
   1292         src_scan += 3;
   1293         continue;
   1294       }
   1295       for (int color = 0; color < 3; color++) {
   1296         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
   1297         dest_scan++;
   1298         src_scan++;
   1299       }
   1300       dest_scan += dest_gap;
   1301     }
   1302   } else {
   1303     for (int col = 0; col < width; col++) {
   1304       uint8_t src_alpha;
   1305       if (clip_scan) {
   1306         src_alpha = src_scan[3] * (*clip_scan++) / 255;
   1307       } else {
   1308         src_alpha = src_scan[3];
   1309       }
   1310       if (src_alpha == 255) {
   1311         *dest_scan++ = *src_scan++;
   1312         *dest_scan++ = *src_scan++;
   1313         *dest_scan++ = *src_scan++;
   1314         dest_scan += dest_gap;
   1315         src_scan++;
   1316         continue;
   1317       }
   1318       if (src_alpha == 0) {
   1319         dest_scan += dest_Bpp;
   1320         src_scan += 4;
   1321         continue;
   1322       }
   1323       for (int color = 0; color < 3; color++) {
   1324         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
   1325         dest_scan++;
   1326         src_scan++;
   1327       }
   1328       dest_scan += dest_gap;
   1329       src_scan++;
   1330     }
   1331   }
   1332 }
   1333 inline void _CompositeRow_Rgb2Rgb_Blend_NoClip(uint8_t* dest_scan,
   1334                                                const uint8_t* src_scan,
   1335                                                int width,
   1336                                                int blend_type,
   1337                                                int dest_Bpp,
   1338                                                int src_Bpp) {
   1339   int blended_colors[3];
   1340   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   1341   int dest_gap = dest_Bpp - 3;
   1342   int src_gap = src_Bpp - 3;
   1343   for (int col = 0; col < width; col++) {
   1344     if (bNonseparableBlend) {
   1345       _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   1346     }
   1347     for (int color = 0; color < 3; color++) {
   1348       int back_color = *dest_scan;
   1349       int src_color = *src_scan;
   1350       int blended = bNonseparableBlend
   1351                         ? blended_colors[color]
   1352                         : _BLEND(blend_type, back_color, src_color);
   1353       *dest_scan = blended;
   1354       dest_scan++;
   1355       src_scan++;
   1356     }
   1357     dest_scan += dest_gap;
   1358     src_scan += src_gap;
   1359   }
   1360 }
   1361 inline void _CompositeRow_Rgb2Rgb_Blend_Clip(uint8_t* dest_scan,
   1362                                              const uint8_t* src_scan,
   1363                                              int width,
   1364                                              int blend_type,
   1365                                              int dest_Bpp,
   1366                                              int src_Bpp,
   1367                                              const uint8_t* clip_scan) {
   1368   int blended_colors[3];
   1369   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   1370   int dest_gap = dest_Bpp - 3;
   1371   int src_gap = src_Bpp - 3;
   1372   for (int col = 0; col < width; col++) {
   1373     uint8_t src_alpha = *clip_scan++;
   1374     if (src_alpha == 0) {
   1375       dest_scan += dest_Bpp;
   1376       src_scan += src_Bpp;
   1377       continue;
   1378     }
   1379     if (bNonseparableBlend) {
   1380       _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   1381     }
   1382     for (int color = 0; color < 3; color++) {
   1383       int src_color = *src_scan;
   1384       int back_color = *dest_scan;
   1385       int blended = bNonseparableBlend
   1386                         ? blended_colors[color]
   1387                         : _BLEND(blend_type, back_color, src_color);
   1388       *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
   1389       dest_scan++;
   1390       src_scan++;
   1391     }
   1392     dest_scan += dest_gap;
   1393     src_scan += src_gap;
   1394   }
   1395 }
   1396 inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip(uint8_t* dest_scan,
   1397                                                  const uint8_t* src_scan,
   1398                                                  int width,
   1399                                                  int dest_Bpp,
   1400                                                  int src_Bpp) {
   1401   if (dest_Bpp == src_Bpp) {
   1402     FXSYS_memcpy(dest_scan, src_scan, width * dest_Bpp);
   1403     return;
   1404   }
   1405   for (int col = 0; col < width; col++) {
   1406     dest_scan[0] = src_scan[0];
   1407     dest_scan[1] = src_scan[1];
   1408     dest_scan[2] = src_scan[2];
   1409     dest_scan += dest_Bpp;
   1410     src_scan += src_Bpp;
   1411   }
   1412 }
   1413 inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip(uint8_t* dest_scan,
   1414                                                const uint8_t* src_scan,
   1415                                                int width,
   1416                                                int dest_Bpp,
   1417                                                int src_Bpp,
   1418                                                const uint8_t* clip_scan) {
   1419   for (int col = 0; col < width; col++) {
   1420     int src_alpha = clip_scan[col];
   1421     if (src_alpha == 255) {
   1422       dest_scan[0] = src_scan[0];
   1423       dest_scan[1] = src_scan[1];
   1424       dest_scan[2] = src_scan[2];
   1425     } else if (src_alpha) {
   1426       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
   1427       dest_scan++;
   1428       src_scan++;
   1429       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
   1430       dest_scan++;
   1431       src_scan++;
   1432       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
   1433       dest_scan += dest_Bpp - 2;
   1434       src_scan += src_Bpp - 2;
   1435       continue;
   1436     }
   1437     dest_scan += dest_Bpp;
   1438     src_scan += src_Bpp;
   1439   }
   1440 }
   1441 void _CompositeRow_Argb2Argb_Transform(uint8_t* dest_scan,
   1442                                        const uint8_t* src_scan,
   1443                                        int pixel_count,
   1444                                        int blend_type,
   1445                                        const uint8_t* clip_scan,
   1446                                        uint8_t* dest_alpha_scan,
   1447                                        const uint8_t* src_alpha_scan,
   1448                                        uint8_t* src_cache_scan,
   1449                                        void* pIccTransform) {
   1450   uint8_t* dp = src_cache_scan;
   1451   ICodec_IccModule* pIccModule =
   1452       CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1453   if (src_alpha_scan) {
   1454     if (dest_alpha_scan) {
   1455       pIccModule->TranslateScanline(pIccTransform, dp, src_scan, pixel_count);
   1456     } else {
   1457       for (int col = 0; col < pixel_count; col++) {
   1458         pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
   1459         dp[3] = *src_alpha_scan++;
   1460         src_scan += 3;
   1461         dp += 4;
   1462       }
   1463       src_alpha_scan = NULL;
   1464     }
   1465   } else {
   1466     if (dest_alpha_scan) {
   1467       int blended_colors[3];
   1468       FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   1469       for (int col = 0; col < pixel_count; col++) {
   1470         pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan,
   1471                                       1);
   1472         uint8_t back_alpha = *dest_alpha_scan;
   1473         if (back_alpha == 0) {
   1474           if (clip_scan) {
   1475             int src_alpha = clip_scan[col] * src_scan[3] / 255;
   1476             *dest_alpha_scan = src_alpha;
   1477             *dest_scan++ = *src_cache_scan++;
   1478             *dest_scan++ = *src_cache_scan++;
   1479             *dest_scan++ = *src_cache_scan++;
   1480           } else {
   1481             *dest_alpha_scan = src_scan[3];
   1482             *dest_scan++ = *src_cache_scan++;
   1483             *dest_scan++ = *src_cache_scan++;
   1484             *dest_scan++ = *src_cache_scan++;
   1485           }
   1486           dest_alpha_scan++;
   1487           src_scan += 4;
   1488           continue;
   1489         }
   1490         uint8_t src_alpha;
   1491         if (clip_scan) {
   1492           src_alpha = clip_scan[col] * src_scan[3] / 255;
   1493         } else {
   1494           src_alpha = src_scan[3];
   1495         }
   1496         src_scan += 4;
   1497         if (src_alpha == 0) {
   1498           dest_scan += 3;
   1499           src_cache_scan += 3;
   1500           dest_alpha_scan++;
   1501           continue;
   1502         }
   1503         uint8_t dest_alpha =
   1504             back_alpha + src_alpha - back_alpha * src_alpha / 255;
   1505         *dest_alpha_scan++ = dest_alpha;
   1506         int alpha_ratio = src_alpha * 255 / dest_alpha;
   1507         if (bNonseparableBlend) {
   1508           _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
   1509         }
   1510         for (int color = 0; color < 3; color++) {
   1511           if (blend_type) {
   1512             int blended = bNonseparableBlend
   1513                               ? blended_colors[color]
   1514                               : _BLEND(blend_type, *dest_scan, *src_cache_scan);
   1515             blended = FXDIB_ALPHA_MERGE(*src_cache_scan, blended, back_alpha);
   1516             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   1517           } else {
   1518             *dest_scan =
   1519                 FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, alpha_ratio);
   1520           }
   1521           dest_scan++;
   1522           src_cache_scan++;
   1523         }
   1524       }
   1525       return;
   1526     }
   1527     for (int col = 0; col < pixel_count; col++) {
   1528       pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
   1529       dp[3] = src_scan[3];
   1530       src_scan += 4;
   1531       dp += 4;
   1532     }
   1533   }
   1534   _CompositeRow_Argb2Argb(dest_scan, src_cache_scan, pixel_count, blend_type,
   1535                           clip_scan, dest_alpha_scan, src_alpha_scan);
   1536 }
   1537 void _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(uint8_t* dest_scan,
   1538                                                    const uint8_t* src_scan,
   1539                                                    int width,
   1540                                                    int blend_type,
   1541                                                    int src_Bpp,
   1542                                                    uint8_t* dest_alpha_scan,
   1543                                                    uint8_t* src_cache_scan,
   1544                                                    void* pIccTransform) {
   1545   ICodec_IccModule* pIccModule =
   1546       CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1547   if (src_Bpp == 3) {
   1548     pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan,
   1549                                   width);
   1550   } else {
   1551     uint8_t* dp = src_cache_scan;
   1552     for (int col = 0; col < width; col++) {
   1553       pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
   1554       src_scan += 4;
   1555       dp += 3;
   1556     }
   1557   }
   1558   _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_cache_scan, width,
   1559                                       blend_type, 3, dest_alpha_scan);
   1560 }
   1561 inline void _CompositeRow_Rgb2Argb_Blend_Clip_Transform(
   1562     uint8_t* dest_scan,
   1563     const uint8_t* src_scan,
   1564     int width,
   1565     int blend_type,
   1566     int src_Bpp,
   1567     const uint8_t* clip_scan,
   1568     uint8_t* dest_alpha_scan,
   1569     uint8_t* src_cache_scan,
   1570     void* pIccTransform) {
   1571   ICodec_IccModule* pIccModule =
   1572       CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1573   if (src_Bpp == 3) {
   1574     pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan,
   1575                                   width);
   1576   } else {
   1577     uint8_t* dp = src_cache_scan;
   1578     for (int col = 0; col < width; col++) {
   1579       pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
   1580       src_scan += 4;
   1581       dp += 3;
   1582     }
   1583   }
   1584   _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_cache_scan, width,
   1585                                     blend_type, 3, clip_scan, dest_alpha_scan);
   1586 }
   1587 inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(
   1588     uint8_t* dest_scan,
   1589     const uint8_t* src_scan,
   1590     int width,
   1591     int src_Bpp,
   1592     const uint8_t* clip_scan,
   1593     uint8_t* dest_alpha_scan,
   1594     uint8_t* src_cache_scan,
   1595     void* pIccTransform) {
   1596   ICodec_IccModule* pIccModule =
   1597       CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1598   if (src_Bpp == 3) {
   1599     pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan,
   1600                                   width);
   1601   } else {
   1602     uint8_t* dp = src_cache_scan;
   1603     for (int col = 0; col < width; col++) {
   1604       pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
   1605       src_scan += 4;
   1606       dp += 3;
   1607     }
   1608   }
   1609   _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_cache_scan, width, 3,
   1610                                       clip_scan, dest_alpha_scan);
   1611 }
   1612 inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(
   1613     uint8_t* dest_scan,
   1614     const uint8_t* src_scan,
   1615     int width,
   1616     int src_Bpp,
   1617     uint8_t* dest_alpha_scan,
   1618     uint8_t* src_cache_scan,
   1619     void* pIccTransform) {
   1620   ICodec_IccModule* pIccModule =
   1621       CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1622   if (src_Bpp == 3) {
   1623     pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan,
   1624                                   width);
   1625   } else {
   1626     uint8_t* dp = src_cache_scan;
   1627     for (int col = 0; col < width; col++) {
   1628       pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
   1629       src_scan += 4;
   1630       dp += 3;
   1631     }
   1632   }
   1633   _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_cache_scan, width, 3,
   1634                                         dest_alpha_scan);
   1635 }
   1636 inline void _CompositeRow_Argb2Rgb_Blend_Transform(
   1637     uint8_t* dest_scan,
   1638     const uint8_t* src_scan,
   1639     int width,
   1640     int blend_type,
   1641     int dest_Bpp,
   1642     const uint8_t* clip_scan,
   1643     const uint8_t* src_alpha_scan,
   1644     uint8_t* src_cache_scan,
   1645     void* pIccTransform) {
   1646   ICodec_IccModule* pIccModule =
   1647       CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1648   if (src_alpha_scan) {
   1649     pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan,
   1650                                   width);
   1651   } else {
   1652     int blended_colors[3];
   1653     FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   1654     int dest_gap = dest_Bpp - 3;
   1655     for (int col = 0; col < width; col++) {
   1656       pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
   1657       uint8_t src_alpha;
   1658       if (clip_scan) {
   1659         src_alpha = src_scan[3] * (*clip_scan++) / 255;
   1660       } else {
   1661         src_alpha = src_scan[3];
   1662       }
   1663       src_scan += 4;
   1664       if (src_alpha == 0) {
   1665         dest_scan += dest_Bpp;
   1666         src_cache_scan += 3;
   1667         continue;
   1668       }
   1669       if (bNonseparableBlend) {
   1670         _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
   1671       }
   1672       for (int color = 0; color < 3; color++) {
   1673         int back_color = *dest_scan;
   1674         int blended = bNonseparableBlend
   1675                           ? blended_colors[color]
   1676                           : _BLEND(blend_type, back_color, *src_cache_scan);
   1677         *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
   1678         dest_scan++;
   1679         src_cache_scan++;
   1680       }
   1681       dest_scan += dest_gap;
   1682     }
   1683     return;
   1684   }
   1685   _CompositeRow_Argb2Rgb_Blend(dest_scan, src_cache_scan, width, blend_type,
   1686                                dest_Bpp, clip_scan, src_alpha_scan);
   1687 }
   1688 inline void _CompositeRow_Argb2Rgb_NoBlend_Transform(
   1689     uint8_t* dest_scan,
   1690     const uint8_t* src_scan,
   1691     int width,
   1692     int dest_Bpp,
   1693     const uint8_t* clip_scan,
   1694     const uint8_t* src_alpha_scan,
   1695     uint8_t* src_cache_scan,
   1696     void* pIccTransform) {
   1697   ICodec_IccModule* pIccModule =
   1698       CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1699   if (src_alpha_scan) {
   1700     pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan,
   1701                                   width);
   1702   } else {
   1703     int dest_gap = dest_Bpp - 3;
   1704     for (int col = 0; col < width; col++) {
   1705       pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
   1706       uint8_t src_alpha;
   1707       if (clip_scan) {
   1708         src_alpha = src_scan[3] * (*clip_scan++) / 255;
   1709       } else {
   1710         src_alpha = src_scan[3];
   1711       }
   1712       src_scan += 4;
   1713       if (src_alpha == 255) {
   1714         *dest_scan++ = *src_cache_scan++;
   1715         *dest_scan++ = *src_cache_scan++;
   1716         *dest_scan++ = *src_cache_scan++;
   1717         dest_scan += dest_gap;
   1718         continue;
   1719       }
   1720       if (src_alpha == 0) {
   1721         dest_scan += dest_Bpp;
   1722         src_cache_scan += 3;
   1723         continue;
   1724       }
   1725       for (int color = 0; color < 3; color++) {
   1726         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, src_alpha);
   1727         dest_scan++;
   1728         src_cache_scan++;
   1729       }
   1730       dest_scan += dest_gap;
   1731     }
   1732     return;
   1733   }
   1734   _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_cache_scan, width, dest_Bpp,
   1735                                  clip_scan, src_alpha_scan);
   1736 }
   1737 inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(
   1738     uint8_t* dest_scan,
   1739     const uint8_t* src_scan,
   1740     int width,
   1741     int blend_type,
   1742     int dest_Bpp,
   1743     int src_Bpp,
   1744     uint8_t* src_cache_scan,
   1745     void* pIccTransform) {
   1746   ICodec_IccModule* pIccModule =
   1747       CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1748   if (src_Bpp == 3) {
   1749     pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan,
   1750                                   width);
   1751   } else {
   1752     uint8_t* dp = src_cache_scan;
   1753     for (int col = 0; col < width; col++) {
   1754       pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
   1755       src_scan += 4;
   1756       dp += 3;
   1757     }
   1758   }
   1759   _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_cache_scan, width,
   1760                                      blend_type, dest_Bpp, 3);
   1761 }
   1762 inline void _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(uint8_t* dest_scan,
   1763                                                        const uint8_t* src_scan,
   1764                                                        int width,
   1765                                                        int blend_type,
   1766                                                        int dest_Bpp,
   1767                                                        int src_Bpp,
   1768                                                        const uint8_t* clip_scan,
   1769                                                        uint8_t* src_cache_scan,
   1770                                                        void* pIccTransform) {
   1771   ICodec_IccModule* pIccModule =
   1772       CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1773   if (src_Bpp == 3) {
   1774     pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan,
   1775                                   width);
   1776   } else {
   1777     uint8_t* dp = src_cache_scan;
   1778     for (int col = 0; col < width; col++) {
   1779       pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
   1780       src_scan += 4;
   1781       dp += 3;
   1782     }
   1783   }
   1784   _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type,
   1785                                    dest_Bpp, 3, clip_scan);
   1786 }
   1787 inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(
   1788     uint8_t* dest_scan,
   1789     const uint8_t* src_scan,
   1790     int width,
   1791     int dest_Bpp,
   1792     int src_Bpp,
   1793     uint8_t* src_cache_scan,
   1794     void* pIccTransform) {
   1795   ICodec_IccModule* pIccModule =
   1796       CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1797   if (src_Bpp == 3) {
   1798     pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan,
   1799                                   width);
   1800   } else {
   1801     uint8_t* dp = src_cache_scan;
   1802     for (int col = 0; col < width; col++) {
   1803       pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
   1804       src_scan += 4;
   1805       dp += 3;
   1806     }
   1807   }
   1808   _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_cache_scan, width,
   1809                                        dest_Bpp, 3);
   1810 }
   1811 inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(
   1812     uint8_t* dest_scan,
   1813     const uint8_t* src_scan,
   1814     int width,
   1815     int dest_Bpp,
   1816     int src_Bpp,
   1817     const uint8_t* clip_scan,
   1818     uint8_t* src_cache_scan,
   1819     void* pIccTransform) {
   1820   ICodec_IccModule* pIccModule =
   1821       CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1822   if (src_Bpp == 3) {
   1823     pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan,
   1824                                   width);
   1825   } else {
   1826     uint8_t* dp = src_cache_scan;
   1827     for (int col = 0; col < width; col++) {
   1828       pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
   1829       src_scan += 4;
   1830       dp += 3;
   1831     }
   1832   }
   1833   _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_cache_scan, width, dest_Bpp,
   1834                                      3, clip_scan);
   1835 }
   1836 inline void _CompositeRow_8bppPal2Gray(uint8_t* dest_scan,
   1837                                        const uint8_t* src_scan,
   1838                                        const uint8_t* pPalette,
   1839                                        int pixel_count,
   1840                                        int blend_type,
   1841                                        const uint8_t* clip_scan,
   1842                                        const uint8_t* src_alpha_scan) {
   1843   if (src_alpha_scan) {
   1844     if (blend_type) {
   1845       FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   1846       int blended_color;
   1847       for (int col = 0; col < pixel_count; col++) {
   1848         uint8_t gray = pPalette[*src_scan];
   1849         int src_alpha = *src_alpha_scan++;
   1850         if (clip_scan) {
   1851           src_alpha = clip_scan[col] * src_alpha / 255;
   1852         }
   1853         if (bNonseparableBlend) {
   1854           blended_color =
   1855               blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
   1856         }
   1857         gray = bNonseparableBlend ? blended_color
   1858                                   : _BLEND(blend_type, *dest_scan, gray);
   1859         if (src_alpha) {
   1860           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
   1861         } else {
   1862           *dest_scan = gray;
   1863         }
   1864         dest_scan++;
   1865         src_scan++;
   1866       }
   1867       return;
   1868     }
   1869     for (int col = 0; col < pixel_count; col++) {
   1870       uint8_t gray = pPalette[*src_scan];
   1871       int src_alpha = *src_alpha_scan++;
   1872       if (clip_scan) {
   1873         src_alpha = clip_scan[col] * src_alpha / 255;
   1874       }
   1875       if (src_alpha) {
   1876         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
   1877       } else {
   1878         *dest_scan = gray;
   1879       }
   1880       dest_scan++;
   1881       src_scan++;
   1882     }
   1883   } else {
   1884     if (blend_type) {
   1885       FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   1886       int blended_color;
   1887       for (int col = 0; col < pixel_count; col++) {
   1888         uint8_t gray = pPalette[*src_scan];
   1889         if (bNonseparableBlend) {
   1890           blended_color =
   1891               blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
   1892         }
   1893         gray = bNonseparableBlend ? blended_color
   1894                                   : _BLEND(blend_type, *dest_scan, gray);
   1895         if (clip_scan && clip_scan[col] < 255) {
   1896           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
   1897         } else {
   1898           *dest_scan = gray;
   1899         }
   1900         dest_scan++;
   1901         src_scan++;
   1902       }
   1903       return;
   1904     }
   1905     for (int col = 0; col < pixel_count; col++) {
   1906       uint8_t gray = pPalette[*src_scan];
   1907       if (clip_scan && clip_scan[col] < 255) {
   1908         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
   1909       } else {
   1910         *dest_scan = gray;
   1911       }
   1912       dest_scan++;
   1913       src_scan++;
   1914     }
   1915   }
   1916 }
   1917 inline void _CompositeRow_8bppPal2Graya(uint8_t* dest_scan,
   1918                                         const uint8_t* src_scan,
   1919                                         const uint8_t* pPalette,
   1920                                         int pixel_count,
   1921                                         int blend_type,
   1922                                         const uint8_t* clip_scan,
   1923                                         uint8_t* dest_alpha_scan,
   1924                                         const uint8_t* src_alpha_scan) {
   1925   if (src_alpha_scan) {
   1926     if (blend_type) {
   1927       FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   1928       int blended_color;
   1929       for (int col = 0; col < pixel_count; col++) {
   1930         uint8_t gray = pPalette[*src_scan];
   1931         src_scan++;
   1932         uint8_t back_alpha = *dest_alpha_scan;
   1933         if (back_alpha == 0) {
   1934           int src_alpha = *src_alpha_scan++;
   1935           if (clip_scan) {
   1936             src_alpha = clip_scan[col] * src_alpha / 255;
   1937           }
   1938           if (src_alpha) {
   1939             *dest_scan = gray;
   1940             *dest_alpha_scan = src_alpha;
   1941           }
   1942           dest_scan++;
   1943           dest_alpha_scan++;
   1944           continue;
   1945         }
   1946         uint8_t src_alpha = *src_alpha_scan++;
   1947         if (clip_scan) {
   1948           src_alpha = clip_scan[col] * src_alpha / 255;
   1949         }
   1950         if (src_alpha == 0) {
   1951           dest_scan++;
   1952           dest_alpha_scan++;
   1953           continue;
   1954         }
   1955         *dest_alpha_scan =
   1956             back_alpha + src_alpha - back_alpha * src_alpha / 255;
   1957         int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
   1958         if (bNonseparableBlend) {
   1959           blended_color =
   1960               blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
   1961         }
   1962         gray = bNonseparableBlend ? blended_color
   1963                                   : _BLEND(blend_type, *dest_scan, gray);
   1964         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
   1965         dest_alpha_scan++;
   1966         dest_scan++;
   1967       }
   1968       return;
   1969     }
   1970     for (int col = 0; col < pixel_count; col++) {
   1971       uint8_t gray = pPalette[*src_scan];
   1972       src_scan++;
   1973       uint8_t back_alpha = *dest_alpha_scan;
   1974       if (back_alpha == 0) {
   1975         int src_alpha = *src_alpha_scan++;
   1976         if (clip_scan) {
   1977           src_alpha = clip_scan[col] * src_alpha / 255;
   1978         }
   1979         if (src_alpha) {
   1980           *dest_scan = gray;
   1981           *dest_alpha_scan = src_alpha;
   1982         }
   1983         dest_scan++;
   1984         dest_alpha_scan++;
   1985         continue;
   1986       }
   1987       uint8_t src_alpha = *src_alpha_scan++;
   1988       if (clip_scan) {
   1989         src_alpha = clip_scan[col] * src_alpha / 255;
   1990       }
   1991       if (src_alpha == 0) {
   1992         dest_scan++;
   1993         dest_alpha_scan++;
   1994         continue;
   1995       }
   1996       *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   1997       int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
   1998       dest_alpha_scan++;
   1999       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
   2000       dest_scan++;
   2001     }
   2002   } else {
   2003     if (blend_type) {
   2004       FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   2005       int blended_color;
   2006       for (int col = 0; col < pixel_count; col++) {
   2007         uint8_t gray = pPalette[*src_scan];
   2008         src_scan++;
   2009         if (!clip_scan || clip_scan[col] == 255) {
   2010           *dest_scan++ = gray;
   2011           *dest_alpha_scan++ = 255;
   2012           continue;
   2013         }
   2014         int src_alpha = clip_scan[col];
   2015         if (src_alpha == 0) {
   2016           dest_scan++;
   2017           dest_alpha_scan++;
   2018           continue;
   2019         }
   2020         int back_alpha = *dest_alpha_scan;
   2021         uint8_t dest_alpha =
   2022             back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2023         *dest_alpha_scan++ = dest_alpha;
   2024         int alpha_ratio = src_alpha * 255 / dest_alpha;
   2025         if (bNonseparableBlend) {
   2026           blended_color =
   2027               blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
   2028         }
   2029         gray = bNonseparableBlend ? blended_color
   2030                                   : _BLEND(blend_type, *dest_scan, gray);
   2031         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
   2032         dest_scan++;
   2033       }
   2034       return;
   2035     }
   2036     for (int col = 0; col < pixel_count; col++) {
   2037       uint8_t gray = pPalette[*src_scan];
   2038       src_scan++;
   2039       if (!clip_scan || clip_scan[col] == 255) {
   2040         *dest_scan++ = gray;
   2041         *dest_alpha_scan++ = 255;
   2042         continue;
   2043       }
   2044       int src_alpha = clip_scan[col];
   2045       if (src_alpha == 0) {
   2046         dest_scan++;
   2047         dest_alpha_scan++;
   2048         continue;
   2049       }
   2050       int back_alpha = *dest_alpha_scan;
   2051       uint8_t dest_alpha =
   2052           back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2053       *dest_alpha_scan++ = dest_alpha;
   2054       int alpha_ratio = src_alpha * 255 / dest_alpha;
   2055       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
   2056       dest_scan++;
   2057     }
   2058   }
   2059 }
   2060 inline void _CompositeRow_1bppPal2Gray(uint8_t* dest_scan,
   2061                                        const uint8_t* src_scan,
   2062                                        int src_left,
   2063                                        const uint8_t* pPalette,
   2064                                        int pixel_count,
   2065                                        int blend_type,
   2066                                        const uint8_t* clip_scan) {
   2067   int reset_gray = pPalette[0];
   2068   int set_gray = pPalette[1];
   2069   if (blend_type) {
   2070     FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   2071     int blended_color;
   2072     for (int col = 0; col < pixel_count; col++) {
   2073       uint8_t gray =
   2074           (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8)))
   2075               ? set_gray
   2076               : reset_gray;
   2077       if (bNonseparableBlend) {
   2078         blended_color =
   2079             blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
   2080       }
   2081       gray = bNonseparableBlend ? blended_color
   2082                                 : _BLEND(blend_type, *dest_scan, gray);
   2083       if (clip_scan && clip_scan[col] < 255) {
   2084         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
   2085       } else {
   2086         *dest_scan = gray;
   2087       }
   2088       dest_scan++;
   2089     }
   2090     return;
   2091   }
   2092   for (int col = 0; col < pixel_count; col++) {
   2093     uint8_t gray =
   2094         (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8)))
   2095             ? set_gray
   2096             : reset_gray;
   2097     if (clip_scan && clip_scan[col] < 255) {
   2098       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
   2099     } else {
   2100       *dest_scan = gray;
   2101     }
   2102     dest_scan++;
   2103   }
   2104 }
   2105 inline void _CompositeRow_1bppPal2Graya(uint8_t* dest_scan,
   2106                                         const uint8_t* src_scan,
   2107                                         int src_left,
   2108                                         const uint8_t* pPalette,
   2109                                         int pixel_count,
   2110                                         int blend_type,
   2111                                         const uint8_t* clip_scan,
   2112                                         uint8_t* dest_alpha_scan) {
   2113   int reset_gray = pPalette[0];
   2114   int set_gray = pPalette[1];
   2115   if (blend_type) {
   2116     FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   2117     int blended_color;
   2118     for (int col = 0; col < pixel_count; col++) {
   2119       uint8_t gray =
   2120           (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8)))
   2121               ? set_gray
   2122               : reset_gray;
   2123       if (!clip_scan || clip_scan[col] == 255) {
   2124         *dest_scan++ = gray;
   2125         *dest_alpha_scan++ = 255;
   2126         continue;
   2127       }
   2128       int src_alpha = clip_scan[col];
   2129       if (src_alpha == 0) {
   2130         dest_scan++;
   2131         dest_alpha_scan++;
   2132         continue;
   2133       }
   2134       int back_alpha = *dest_alpha_scan;
   2135       uint8_t dest_alpha =
   2136           back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2137       *dest_alpha_scan++ = dest_alpha;
   2138       int alpha_ratio = src_alpha * 255 / dest_alpha;
   2139       if (bNonseparableBlend) {
   2140         blended_color =
   2141             blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
   2142       }
   2143       gray = bNonseparableBlend ? blended_color
   2144                                 : _BLEND(blend_type, *dest_scan, gray);
   2145       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
   2146       dest_scan++;
   2147     }
   2148     return;
   2149   }
   2150   for (int col = 0; col < pixel_count; col++) {
   2151     uint8_t gray =
   2152         (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8)))
   2153             ? set_gray
   2154             : reset_gray;
   2155     if (!clip_scan || clip_scan[col] == 255) {
   2156       *dest_scan++ = gray;
   2157       *dest_alpha_scan++ = 255;
   2158       continue;
   2159     }
   2160     int src_alpha = clip_scan[col];
   2161     if (src_alpha == 0) {
   2162       dest_scan++;
   2163       dest_alpha_scan++;
   2164       continue;
   2165     }
   2166     int back_alpha = *dest_alpha_scan;
   2167     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2168     *dest_alpha_scan++ = dest_alpha;
   2169     int alpha_ratio = src_alpha * 255 / dest_alpha;
   2170     *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
   2171     dest_scan++;
   2172   }
   2173 }
   2174 inline void _CompositeRow_8bppRgb2Rgb_NoBlend(uint8_t* dest_scan,
   2175                                               const uint8_t* src_scan,
   2176                                               FX_DWORD* pPalette,
   2177                                               int pixel_count,
   2178                                               int DestBpp,
   2179                                               const uint8_t* clip_scan,
   2180                                               const uint8_t* src_alpha_scan) {
   2181   if (src_alpha_scan) {
   2182     int dest_gap = DestBpp - 3;
   2183     FX_ARGB argb = 0;
   2184     for (int col = 0; col < pixel_count; col++) {
   2185       argb = pPalette[*src_scan];
   2186       int src_r = FXARGB_R(argb);
   2187       int src_g = FXARGB_G(argb);
   2188       int src_b = FXARGB_B(argb);
   2189       src_scan++;
   2190       uint8_t src_alpha = 0;
   2191       if (clip_scan) {
   2192         src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
   2193       } else {
   2194         src_alpha = *src_alpha_scan++;
   2195       }
   2196       if (src_alpha == 255) {
   2197         *dest_scan++ = src_b;
   2198         *dest_scan++ = src_g;
   2199         *dest_scan++ = src_r;
   2200         dest_scan += dest_gap;
   2201         continue;
   2202       }
   2203       if (src_alpha == 0) {
   2204         dest_scan += DestBpp;
   2205         continue;
   2206       }
   2207       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
   2208       dest_scan++;
   2209       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
   2210       dest_scan++;
   2211       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
   2212       dest_scan++;
   2213       dest_scan += dest_gap;
   2214     }
   2215   } else {
   2216     FX_ARGB argb = 0;
   2217     for (int col = 0; col < pixel_count; col++) {
   2218       argb = pPalette[*src_scan];
   2219       int src_r = FXARGB_R(argb);
   2220       int src_g = FXARGB_G(argb);
   2221       int src_b = FXARGB_B(argb);
   2222       if (clip_scan && clip_scan[col] < 255) {
   2223         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
   2224         dest_scan++;
   2225         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
   2226         dest_scan++;
   2227         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
   2228         dest_scan++;
   2229       } else {
   2230         *dest_scan++ = src_b;
   2231         *dest_scan++ = src_g;
   2232         *dest_scan++ = src_r;
   2233       }
   2234       if (DestBpp == 4) {
   2235         dest_scan++;
   2236       }
   2237       src_scan++;
   2238     }
   2239   }
   2240 }
   2241 inline void _CompositeRow_1bppRgb2Rgb_NoBlend(uint8_t* dest_scan,
   2242                                               const uint8_t* src_scan,
   2243                                               int src_left,
   2244                                               FX_DWORD* pPalette,
   2245                                               int pixel_count,
   2246                                               int DestBpp,
   2247                                               const uint8_t* clip_scan) {
   2248   int reset_r, reset_g, reset_b;
   2249   int set_r, set_g, set_b;
   2250   reset_r = FXARGB_R(pPalette[0]);
   2251   reset_g = FXARGB_G(pPalette[0]);
   2252   reset_b = FXARGB_B(pPalette[0]);
   2253   set_r = FXARGB_R(pPalette[1]);
   2254   set_g = FXARGB_G(pPalette[1]);
   2255   set_b = FXARGB_B(pPalette[1]);
   2256   for (int col = 0; col < pixel_count; col++) {
   2257     int src_r, src_g, src_b;
   2258     if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
   2259       src_r = set_r;
   2260       src_g = set_g;
   2261       src_b = set_b;
   2262     } else {
   2263       src_r = reset_r;
   2264       src_g = reset_g;
   2265       src_b = reset_b;
   2266     }
   2267     if (clip_scan && clip_scan[col] < 255) {
   2268       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
   2269       dest_scan++;
   2270       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
   2271       dest_scan++;
   2272       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
   2273       dest_scan++;
   2274     } else {
   2275       *dest_scan++ = src_b;
   2276       *dest_scan++ = src_g;
   2277       *dest_scan++ = src_r;
   2278     }
   2279     if (DestBpp == 4) {
   2280       dest_scan++;
   2281     }
   2282   }
   2283 }
   2284 inline void _CompositeRow_8bppRgb2Argb_NoBlend(uint8_t* dest_scan,
   2285                                                const uint8_t* src_scan,
   2286                                                int width,
   2287                                                FX_DWORD* pPalette,
   2288                                                const uint8_t* clip_scan,
   2289                                                const uint8_t* src_alpha_scan) {
   2290   if (src_alpha_scan) {
   2291     for (int col = 0; col < width; col++) {
   2292       FX_ARGB argb = pPalette[*src_scan];
   2293       src_scan++;
   2294       int src_r = FXARGB_R(argb);
   2295       int src_g = FXARGB_G(argb);
   2296       int src_b = FXARGB_B(argb);
   2297       uint8_t back_alpha = dest_scan[3];
   2298       if (back_alpha == 0) {
   2299         if (clip_scan) {
   2300           int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
   2301           FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
   2302         } else {
   2303           FXARGB_SETDIB(dest_scan,
   2304                         FXARGB_MAKE(*src_alpha_scan, src_r, src_g, src_b));
   2305         }
   2306         dest_scan += 4;
   2307         src_alpha_scan++;
   2308         continue;
   2309       }
   2310       uint8_t src_alpha;
   2311       if (clip_scan) {
   2312         src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
   2313       } else {
   2314         src_alpha = *src_alpha_scan++;
   2315       }
   2316       if (src_alpha == 0) {
   2317         dest_scan += 4;
   2318         continue;
   2319       }
   2320       uint8_t dest_alpha =
   2321           back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2322       dest_scan[3] = dest_alpha;
   2323       int alpha_ratio = src_alpha * 255 / dest_alpha;
   2324       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
   2325       dest_scan++;
   2326       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
   2327       dest_scan++;
   2328       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
   2329       dest_scan++;
   2330       dest_scan++;
   2331     }
   2332   } else
   2333     for (int col = 0; col < width; col++) {
   2334       FX_ARGB argb = pPalette[*src_scan];
   2335       int src_r = FXARGB_R(argb);
   2336       int src_g = FXARGB_G(argb);
   2337       int src_b = FXARGB_B(argb);
   2338       if (!clip_scan || clip_scan[col] == 255) {
   2339         *dest_scan++ = src_b;
   2340         *dest_scan++ = src_g;
   2341         *dest_scan++ = src_r;
   2342         *dest_scan++ = 255;
   2343         src_scan++;
   2344         continue;
   2345       }
   2346       int src_alpha = clip_scan[col];
   2347       if (src_alpha == 0) {
   2348         dest_scan += 4;
   2349         src_scan++;
   2350         continue;
   2351       }
   2352       int back_alpha = dest_scan[3];
   2353       uint8_t dest_alpha =
   2354           back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2355       dest_scan[3] = dest_alpha;
   2356       int alpha_ratio = src_alpha * 255 / dest_alpha;
   2357       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
   2358       dest_scan++;
   2359       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
   2360       dest_scan++;
   2361       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
   2362       dest_scan++;
   2363       dest_scan++;
   2364       src_scan++;
   2365     }
   2366 }
   2367 void _CompositeRow_8bppRgb2Rgba_NoBlend(uint8_t* dest_scan,
   2368                                         const uint8_t* src_scan,
   2369                                         int width,
   2370                                         FX_DWORD* pPalette,
   2371                                         const uint8_t* clip_scan,
   2372                                         uint8_t* dest_alpha_scan,
   2373                                         const uint8_t* src_alpha_scan) {
   2374   if (src_alpha_scan) {
   2375     for (int col = 0; col < width; col++) {
   2376       FX_ARGB argb = pPalette[*src_scan];
   2377       src_scan++;
   2378       int src_r = FXARGB_R(argb);
   2379       int src_g = FXARGB_G(argb);
   2380       int src_b = FXARGB_B(argb);
   2381       uint8_t back_alpha = *dest_alpha_scan;
   2382       if (back_alpha == 0) {
   2383         if (clip_scan) {
   2384           int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
   2385           *dest_alpha_scan++ = src_alpha;
   2386         } else {
   2387           *dest_alpha_scan++ = *src_alpha_scan;
   2388         }
   2389         *dest_scan++ = src_b;
   2390         *dest_scan++ = src_g;
   2391         *dest_scan++ = src_r;
   2392         src_alpha_scan++;
   2393         continue;
   2394       }
   2395       uint8_t src_alpha;
   2396       if (clip_scan) {
   2397         src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
   2398       } else {
   2399         src_alpha = *src_alpha_scan++;
   2400       }
   2401       if (src_alpha == 0) {
   2402         dest_scan += 3;
   2403         dest_alpha_scan++;
   2404         continue;
   2405       }
   2406       uint8_t dest_alpha =
   2407           back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2408       *dest_alpha_scan++ = dest_alpha;
   2409       int alpha_ratio = src_alpha * 255 / dest_alpha;
   2410       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
   2411       dest_scan++;
   2412       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
   2413       dest_scan++;
   2414       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
   2415       dest_scan++;
   2416     }
   2417   } else
   2418     for (int col = 0; col < width; col++) {
   2419       FX_ARGB argb = pPalette[*src_scan];
   2420       int src_r = FXARGB_R(argb);
   2421       int src_g = FXARGB_G(argb);
   2422       int src_b = FXARGB_B(argb);
   2423       if (!clip_scan || clip_scan[col] == 255) {
   2424         *dest_scan++ = src_b;
   2425         *dest_scan++ = src_g;
   2426         *dest_scan++ = src_r;
   2427         *dest_alpha_scan++ = 255;
   2428         src_scan++;
   2429         continue;
   2430       }
   2431       int src_alpha = clip_scan[col];
   2432       if (src_alpha == 0) {
   2433         dest_scan += 3;
   2434         dest_alpha_scan++;
   2435         src_scan++;
   2436         continue;
   2437       }
   2438       int back_alpha = *dest_alpha_scan;
   2439       uint8_t dest_alpha =
   2440           back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2441       *dest_alpha_scan++ = dest_alpha;
   2442       int alpha_ratio = src_alpha * 255 / dest_alpha;
   2443       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
   2444       dest_scan++;
   2445       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
   2446       dest_scan++;
   2447       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
   2448       dest_scan++;
   2449       src_scan++;
   2450     }
   2451 }
   2452 inline void _CompositeRow_1bppRgb2Argb_NoBlend(uint8_t* dest_scan,
   2453                                                const uint8_t* src_scan,
   2454                                                int src_left,
   2455                                                int width,
   2456                                                FX_DWORD* pPalette,
   2457                                                const uint8_t* clip_scan) {
   2458   int reset_r, reset_g, reset_b;
   2459   int set_r, set_g, set_b;
   2460   reset_r = FXARGB_R(pPalette[0]);
   2461   reset_g = FXARGB_G(pPalette[0]);
   2462   reset_b = FXARGB_B(pPalette[0]);
   2463   set_r = FXARGB_R(pPalette[1]);
   2464   set_g = FXARGB_G(pPalette[1]);
   2465   set_b = FXARGB_B(pPalette[1]);
   2466   for (int col = 0; col < width; col++) {
   2467     int src_r, src_g, src_b;
   2468     if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
   2469       src_r = set_r;
   2470       src_g = set_g;
   2471       src_b = set_b;
   2472     } else {
   2473       src_r = reset_r;
   2474       src_g = reset_g;
   2475       src_b = reset_b;
   2476     }
   2477     if (!clip_scan || clip_scan[col] == 255) {
   2478       *dest_scan++ = src_b;
   2479       *dest_scan++ = src_g;
   2480       *dest_scan++ = src_r;
   2481       *dest_scan++ = 255;
   2482       continue;
   2483     }
   2484     int src_alpha = clip_scan[col];
   2485     if (src_alpha == 0) {
   2486       dest_scan += 4;
   2487       continue;
   2488     }
   2489     int back_alpha = dest_scan[3];
   2490     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2491     dest_scan[3] = dest_alpha;
   2492     int alpha_ratio = src_alpha * 255 / dest_alpha;
   2493     *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
   2494     dest_scan++;
   2495     *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
   2496     dest_scan++;
   2497     *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
   2498     dest_scan++;
   2499     dest_scan++;
   2500   }
   2501 }
   2502 void _CompositeRow_1bppRgb2Rgba_NoBlend(uint8_t* dest_scan,
   2503                                         const uint8_t* src_scan,
   2504                                         int src_left,
   2505                                         int width,
   2506                                         FX_DWORD* pPalette,
   2507                                         const uint8_t* clip_scan,
   2508                                         uint8_t* dest_alpha_scan) {
   2509   int reset_r, reset_g, reset_b;
   2510   int set_r, set_g, set_b;
   2511   reset_r = FXARGB_R(pPalette[0]);
   2512   reset_g = FXARGB_G(pPalette[0]);
   2513   reset_b = FXARGB_B(pPalette[0]);
   2514   set_r = FXARGB_R(pPalette[1]);
   2515   set_g = FXARGB_G(pPalette[1]);
   2516   set_b = FXARGB_B(pPalette[1]);
   2517   for (int col = 0; col < width; col++) {
   2518     int src_r, src_g, src_b;
   2519     if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
   2520       src_r = set_r;
   2521       src_g = set_g;
   2522       src_b = set_b;
   2523     } else {
   2524       src_r = reset_r;
   2525       src_g = reset_g;
   2526       src_b = reset_b;
   2527     }
   2528     if (!clip_scan || clip_scan[col] == 255) {
   2529       *dest_scan++ = src_b;
   2530       *dest_scan++ = src_g;
   2531       *dest_scan++ = src_r;
   2532       *dest_alpha_scan++ = 255;
   2533       continue;
   2534     }
   2535     int src_alpha = clip_scan[col];
   2536     if (src_alpha == 0) {
   2537       dest_scan += 3;
   2538       dest_alpha_scan++;
   2539       continue;
   2540     }
   2541     int back_alpha = *dest_alpha_scan;
   2542     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2543     *dest_alpha_scan++ = dest_alpha;
   2544     int alpha_ratio = src_alpha * 255 / dest_alpha;
   2545     *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
   2546     dest_scan++;
   2547     *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
   2548     dest_scan++;
   2549     *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
   2550     dest_scan++;
   2551   }
   2552 }
   2553 void _CompositeRow_ByteMask2Argb(uint8_t* dest_scan,
   2554                                  const uint8_t* src_scan,
   2555                                  int mask_alpha,
   2556                                  int src_r,
   2557                                  int src_g,
   2558                                  int src_b,
   2559                                  int pixel_count,
   2560                                  int blend_type,
   2561                                  const uint8_t* clip_scan) {
   2562   for (int col = 0; col < pixel_count; col++) {
   2563     int src_alpha;
   2564     if (clip_scan) {
   2565       src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
   2566     } else {
   2567       src_alpha = mask_alpha * src_scan[col] / 255;
   2568     }
   2569     uint8_t back_alpha = dest_scan[3];
   2570     if (back_alpha == 0) {
   2571       FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
   2572       dest_scan += 4;
   2573       continue;
   2574     }
   2575     if (src_alpha == 0) {
   2576       dest_scan += 4;
   2577       continue;
   2578     }
   2579     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2580     dest_scan[3] = dest_alpha;
   2581     int alpha_ratio = src_alpha * 255 / dest_alpha;
   2582     if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
   2583       int blended_colors[3];
   2584       uint8_t src_scan[3];
   2585       src_scan[0] = src_b;
   2586       src_scan[1] = src_g;
   2587       src_scan[2] = src_r;
   2588       _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   2589       *dest_scan =
   2590           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
   2591       dest_scan++;
   2592       *dest_scan =
   2593           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
   2594       dest_scan++;
   2595       *dest_scan =
   2596           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
   2597     } else if (blend_type) {
   2598       int blended = _BLEND(blend_type, *dest_scan, src_b);
   2599       blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
   2600       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2601       dest_scan++;
   2602       blended = _BLEND(blend_type, *dest_scan, src_g);
   2603       blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
   2604       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2605       dest_scan++;
   2606       blended = _BLEND(blend_type, *dest_scan, src_r);
   2607       blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
   2608       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2609     } else {
   2610       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
   2611       dest_scan++;
   2612       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
   2613       dest_scan++;
   2614       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
   2615     }
   2616     dest_scan += 2;
   2617   }
   2618 }
   2619 void _CompositeRow_ByteMask2Rgba(uint8_t* dest_scan,
   2620                                  const uint8_t* src_scan,
   2621                                  int mask_alpha,
   2622                                  int src_r,
   2623                                  int src_g,
   2624                                  int src_b,
   2625                                  int pixel_count,
   2626                                  int blend_type,
   2627                                  const uint8_t* clip_scan,
   2628                                  uint8_t* dest_alpha_scan) {
   2629   for (int col = 0; col < pixel_count; col++) {
   2630     int src_alpha;
   2631     if (clip_scan) {
   2632       src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
   2633     } else {
   2634       src_alpha = mask_alpha * src_scan[col] / 255;
   2635     }
   2636     uint8_t back_alpha = *dest_alpha_scan;
   2637     if (back_alpha == 0) {
   2638       *dest_scan++ = src_b;
   2639       *dest_scan++ = src_g;
   2640       *dest_scan++ = src_r;
   2641       *dest_alpha_scan++ = src_alpha;
   2642       continue;
   2643     }
   2644     if (src_alpha == 0) {
   2645       dest_scan += 3;
   2646       dest_alpha_scan++;
   2647       continue;
   2648     }
   2649     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2650     *dest_alpha_scan++ = dest_alpha;
   2651     int alpha_ratio = src_alpha * 255 / dest_alpha;
   2652     if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
   2653       int blended_colors[3];
   2654       uint8_t src_scan[3];
   2655       src_scan[0] = src_b;
   2656       src_scan[1] = src_g;
   2657       src_scan[2] = src_r;
   2658       _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   2659       *dest_scan =
   2660           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
   2661       dest_scan++;
   2662       *dest_scan =
   2663           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
   2664       dest_scan++;
   2665       *dest_scan =
   2666           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
   2667       dest_scan++;
   2668     } else if (blend_type) {
   2669       int blended = _BLEND(blend_type, *dest_scan, src_b);
   2670       blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
   2671       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2672       dest_scan++;
   2673       blended = _BLEND(blend_type, *dest_scan, src_g);
   2674       blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
   2675       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2676       dest_scan++;
   2677       blended = _BLEND(blend_type, *dest_scan, src_r);
   2678       blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
   2679       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2680       dest_scan++;
   2681     } else {
   2682       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
   2683       dest_scan++;
   2684       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
   2685       dest_scan++;
   2686       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
   2687       dest_scan++;
   2688     }
   2689   }
   2690 }
   2691 void _CompositeRow_ByteMask2Rgb(uint8_t* dest_scan,
   2692                                 const uint8_t* src_scan,
   2693                                 int mask_alpha,
   2694                                 int src_r,
   2695                                 int src_g,
   2696                                 int src_b,
   2697                                 int pixel_count,
   2698                                 int blend_type,
   2699                                 int Bpp,
   2700                                 const uint8_t* clip_scan) {
   2701   for (int col = 0; col < pixel_count; col++) {
   2702     int src_alpha;
   2703     if (clip_scan) {
   2704       src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
   2705     } else {
   2706       src_alpha = mask_alpha * src_scan[col] / 255;
   2707     }
   2708     if (src_alpha == 0) {
   2709       dest_scan += Bpp;
   2710       continue;
   2711     }
   2712     if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
   2713       int blended_colors[3];
   2714       uint8_t src_scan[3];
   2715       src_scan[0] = src_b;
   2716       src_scan[1] = src_g;
   2717       src_scan[2] = src_r;
   2718       _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   2719       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
   2720       dest_scan++;
   2721       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
   2722       dest_scan++;
   2723       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
   2724     } else if (blend_type) {
   2725       int blended = _BLEND(blend_type, *dest_scan, src_b);
   2726       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
   2727       dest_scan++;
   2728       blended = _BLEND(blend_type, *dest_scan, src_g);
   2729       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
   2730       dest_scan++;
   2731       blended = _BLEND(blend_type, *dest_scan, src_r);
   2732       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
   2733     } else {
   2734       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
   2735       dest_scan++;
   2736       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
   2737       dest_scan++;
   2738       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
   2739     }
   2740     dest_scan += Bpp - 2;
   2741   }
   2742 }
   2743 void _CompositeRow_ByteMask2Mask(uint8_t* dest_scan,
   2744                                  const uint8_t* src_scan,
   2745                                  int mask_alpha,
   2746                                  int pixel_count,
   2747                                  const uint8_t* clip_scan) {
   2748   for (int col = 0; col < pixel_count; col++) {
   2749     int src_alpha;
   2750     if (clip_scan) {
   2751       src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
   2752     } else {
   2753       src_alpha = mask_alpha * src_scan[col] / 255;
   2754     }
   2755     uint8_t back_alpha = *dest_scan;
   2756     if (!back_alpha) {
   2757       *dest_scan = src_alpha;
   2758     } else if (src_alpha) {
   2759       *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2760     }
   2761     dest_scan++;
   2762   }
   2763 }
   2764 void _CompositeRow_ByteMask2Gray(uint8_t* dest_scan,
   2765                                  const uint8_t* src_scan,
   2766                                  int mask_alpha,
   2767                                  int src_gray,
   2768                                  int pixel_count,
   2769                                  const uint8_t* clip_scan) {
   2770   for (int col = 0; col < pixel_count; col++) {
   2771     int src_alpha;
   2772     if (clip_scan) {
   2773       src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
   2774     } else {
   2775       src_alpha = mask_alpha * src_scan[col] / 255;
   2776     }
   2777     if (src_alpha) {
   2778       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
   2779     }
   2780     dest_scan++;
   2781   }
   2782 }
   2783 void _CompositeRow_ByteMask2Graya(uint8_t* dest_scan,
   2784                                   const uint8_t* src_scan,
   2785                                   int mask_alpha,
   2786                                   int src_gray,
   2787                                   int pixel_count,
   2788                                   const uint8_t* clip_scan,
   2789                                   uint8_t* dest_alpha_scan) {
   2790   for (int col = 0; col < pixel_count; col++) {
   2791     int src_alpha;
   2792     if (clip_scan) {
   2793       src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
   2794     } else {
   2795       src_alpha = mask_alpha * src_scan[col] / 255;
   2796     }
   2797     uint8_t back_alpha = *dest_alpha_scan;
   2798     if (back_alpha == 0) {
   2799       *dest_scan++ = src_gray;
   2800       *dest_alpha_scan++ = src_alpha;
   2801       continue;
   2802     }
   2803     if (src_alpha == 0) {
   2804       dest_scan++;
   2805       dest_alpha_scan++;
   2806       continue;
   2807     }
   2808     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2809     *dest_alpha_scan++ = dest_alpha;
   2810     int alpha_ratio = src_alpha * 255 / dest_alpha;
   2811     *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
   2812     dest_scan++;
   2813   }
   2814 }
   2815 void _CompositeRow_BitMask2Argb(uint8_t* dest_scan,
   2816                                 const uint8_t* src_scan,
   2817                                 int mask_alpha,
   2818                                 int src_r,
   2819                                 int src_g,
   2820                                 int src_b,
   2821                                 int src_left,
   2822                                 int pixel_count,
   2823                                 int blend_type,
   2824                                 const uint8_t* clip_scan) {
   2825   if (blend_type == FXDIB_BLEND_NORMAL && !clip_scan && mask_alpha == 255) {
   2826     FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
   2827     for (int col = 0; col < pixel_count; col++) {
   2828       if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
   2829         FXARGB_SETDIB(dest_scan, argb);
   2830       }
   2831       dest_scan += 4;
   2832     }
   2833     return;
   2834   }
   2835   for (int col = 0; col < pixel_count; col++) {
   2836     if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
   2837       dest_scan += 4;
   2838       continue;
   2839     }
   2840     int src_alpha;
   2841     if (clip_scan) {
   2842       src_alpha = mask_alpha * clip_scan[col] / 255;
   2843     } else {
   2844       src_alpha = mask_alpha;
   2845     }
   2846     uint8_t back_alpha = dest_scan[3];
   2847     if (back_alpha == 0) {
   2848       FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
   2849       dest_scan += 4;
   2850       continue;
   2851     }
   2852     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2853     dest_scan[3] = dest_alpha;
   2854     int alpha_ratio = src_alpha * 255 / dest_alpha;
   2855     if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
   2856       int blended_colors[3];
   2857       uint8_t src_scan[3];
   2858       src_scan[0] = src_b;
   2859       src_scan[1] = src_g;
   2860       src_scan[2] = src_r;
   2861       _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   2862       *dest_scan =
   2863           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
   2864       dest_scan++;
   2865       *dest_scan =
   2866           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
   2867       dest_scan++;
   2868       *dest_scan =
   2869           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
   2870     } else if (blend_type) {
   2871       int blended = _BLEND(blend_type, *dest_scan, src_b);
   2872       blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
   2873       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2874       dest_scan++;
   2875       blended = _BLEND(blend_type, *dest_scan, src_g);
   2876       blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
   2877       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2878       dest_scan++;
   2879       blended = _BLEND(blend_type, *dest_scan, src_r);
   2880       blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
   2881       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2882     } else {
   2883       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
   2884       dest_scan++;
   2885       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
   2886       dest_scan++;
   2887       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
   2888     }
   2889     dest_scan += 2;
   2890   }
   2891 }
   2892 void _CompositeRow_BitMask2Rgba(uint8_t* dest_scan,
   2893                                 const uint8_t* src_scan,
   2894                                 int mask_alpha,
   2895                                 int src_r,
   2896                                 int src_g,
   2897                                 int src_b,
   2898                                 int src_left,
   2899                                 int pixel_count,
   2900                                 int blend_type,
   2901                                 const uint8_t* clip_scan,
   2902                                 uint8_t* dest_alpha_scan) {
   2903   if (blend_type == FXDIB_BLEND_NORMAL && !clip_scan && mask_alpha == 255) {
   2904     for (int col = 0; col < pixel_count; col++) {
   2905       if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
   2906         dest_scan[0] = src_b;
   2907         dest_scan[1] = src_g;
   2908         dest_scan[2] = src_r;
   2909         *dest_alpha_scan = mask_alpha;
   2910       }
   2911       dest_scan += 3;
   2912       dest_alpha_scan++;
   2913     }
   2914     return;
   2915   }
   2916   for (int col = 0; col < pixel_count; col++) {
   2917     if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
   2918       dest_scan += 3;
   2919       dest_alpha_scan++;
   2920       continue;
   2921     }
   2922     int src_alpha;
   2923     if (clip_scan) {
   2924       src_alpha = mask_alpha * clip_scan[col] / 255;
   2925     } else {
   2926       src_alpha = mask_alpha;
   2927     }
   2928     uint8_t back_alpha = dest_scan[3];
   2929     if (back_alpha == 0) {
   2930       *dest_scan++ = src_b;
   2931       *dest_scan++ = src_g;
   2932       *dest_scan++ = src_r;
   2933       *dest_alpha_scan++ = mask_alpha;
   2934       continue;
   2935     }
   2936     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   2937     *dest_alpha_scan++ = dest_alpha;
   2938     int alpha_ratio = src_alpha * 255 / dest_alpha;
   2939     if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
   2940       int blended_colors[3];
   2941       uint8_t src_scan[3];
   2942       src_scan[0] = src_b;
   2943       src_scan[1] = src_g;
   2944       src_scan[2] = src_r;
   2945       _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   2946       *dest_scan =
   2947           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
   2948       dest_scan++;
   2949       *dest_scan =
   2950           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
   2951       dest_scan++;
   2952       *dest_scan =
   2953           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
   2954       dest_scan++;
   2955     } else if (blend_type) {
   2956       int blended = _BLEND(blend_type, *dest_scan, src_b);
   2957       blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
   2958       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2959       dest_scan++;
   2960       blended = _BLEND(blend_type, *dest_scan, src_g);
   2961       blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
   2962       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2963       dest_scan++;
   2964       blended = _BLEND(blend_type, *dest_scan, src_r);
   2965       blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
   2966       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
   2967       dest_scan++;
   2968     } else {
   2969       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
   2970       dest_scan++;
   2971       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
   2972       dest_scan++;
   2973       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
   2974       dest_scan++;
   2975     }
   2976   }
   2977 }
   2978 void _CompositeRow_BitMask2Rgb(uint8_t* dest_scan,
   2979                                const uint8_t* src_scan,
   2980                                int mask_alpha,
   2981                                int src_r,
   2982                                int src_g,
   2983                                int src_b,
   2984                                int src_left,
   2985                                int pixel_count,
   2986                                int blend_type,
   2987                                int Bpp,
   2988                                const uint8_t* clip_scan) {
   2989   if (blend_type == FXDIB_BLEND_NORMAL && !clip_scan && mask_alpha == 255) {
   2990     for (int col = 0; col < pixel_count; col++) {
   2991       if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
   2992         dest_scan[2] = src_r;
   2993         dest_scan[1] = src_g;
   2994         dest_scan[0] = src_b;
   2995       }
   2996       dest_scan += Bpp;
   2997     }
   2998     return;
   2999   }
   3000   for (int col = 0; col < pixel_count; col++) {
   3001     if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
   3002       dest_scan += Bpp;
   3003       continue;
   3004     }
   3005     int src_alpha;
   3006     if (clip_scan) {
   3007       src_alpha = mask_alpha * clip_scan[col] / 255;
   3008     } else {
   3009       src_alpha = mask_alpha;
   3010     }
   3011     if (src_alpha == 0) {
   3012       dest_scan += Bpp;
   3013       continue;
   3014     }
   3015     if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
   3016       int blended_colors[3];
   3017       uint8_t src_scan[3];
   3018       src_scan[0] = src_b;
   3019       src_scan[1] = src_g;
   3020       src_scan[2] = src_r;
   3021       _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
   3022       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
   3023       dest_scan++;
   3024       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
   3025       dest_scan++;
   3026       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
   3027     } else if (blend_type) {
   3028       int blended = _BLEND(blend_type, *dest_scan, src_b);
   3029       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
   3030       dest_scan++;
   3031       blended = _BLEND(blend_type, *dest_scan, src_g);
   3032       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
   3033       dest_scan++;
   3034       blended = _BLEND(blend_type, *dest_scan, src_r);
   3035       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
   3036     } else {
   3037       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
   3038       dest_scan++;
   3039       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
   3040       dest_scan++;
   3041       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
   3042     }
   3043     dest_scan += Bpp - 2;
   3044   }
   3045 }
   3046 void _CompositeRow_BitMask2Mask(uint8_t* dest_scan,
   3047                                 const uint8_t* src_scan,
   3048                                 int mask_alpha,
   3049                                 int src_left,
   3050                                 int pixel_count,
   3051                                 const uint8_t* clip_scan) {
   3052   for (int col = 0; col < pixel_count; col++) {
   3053     if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
   3054       dest_scan++;
   3055       continue;
   3056     }
   3057     int src_alpha;
   3058     if (clip_scan) {
   3059       src_alpha = mask_alpha * clip_scan[col] / 255;
   3060     } else {
   3061       src_alpha = mask_alpha;
   3062     }
   3063     uint8_t back_alpha = *dest_scan;
   3064     if (!back_alpha) {
   3065       *dest_scan = src_alpha;
   3066     } else if (src_alpha) {
   3067       *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   3068     }
   3069     dest_scan++;
   3070   }
   3071 }
   3072 void _CompositeRow_BitMask2Gray(uint8_t* dest_scan,
   3073                                 const uint8_t* src_scan,
   3074                                 int mask_alpha,
   3075                                 int src_gray,
   3076                                 int src_left,
   3077                                 int pixel_count,
   3078                                 const uint8_t* clip_scan) {
   3079   for (int col = 0; col < pixel_count; col++) {
   3080     if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
   3081       dest_scan++;
   3082       continue;
   3083     }
   3084     int src_alpha;
   3085     if (clip_scan) {
   3086       src_alpha = mask_alpha * clip_scan[col] / 255;
   3087     } else {
   3088       src_alpha = mask_alpha;
   3089     }
   3090     if (src_alpha) {
   3091       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
   3092     }
   3093     dest_scan++;
   3094   }
   3095 }
   3096 void _CompositeRow_BitMask2Graya(uint8_t* dest_scan,
   3097                                  const uint8_t* src_scan,
   3098                                  int mask_alpha,
   3099                                  int src_gray,
   3100                                  int src_left,
   3101                                  int pixel_count,
   3102                                  const uint8_t* clip_scan,
   3103                                  uint8_t* dest_alpha_scan) {
   3104   for (int col = 0; col < pixel_count; col++) {
   3105     if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
   3106       dest_scan++;
   3107       dest_alpha_scan++;
   3108       continue;
   3109     }
   3110     int src_alpha;
   3111     if (clip_scan) {
   3112       src_alpha = mask_alpha * clip_scan[col] / 255;
   3113     } else {
   3114       src_alpha = mask_alpha;
   3115     }
   3116     uint8_t back_alpha = *dest_alpha_scan;
   3117     if (back_alpha == 0) {
   3118       *dest_scan++ = src_gray;
   3119       *dest_alpha_scan++ = src_alpha;
   3120       continue;
   3121     }
   3122     if (src_alpha == 0) {
   3123       dest_scan++;
   3124       dest_alpha_scan++;
   3125       continue;
   3126     }
   3127     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   3128     *dest_alpha_scan++ = dest_alpha;
   3129     int alpha_ratio = src_alpha * 255 / dest_alpha;
   3130     *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
   3131     dest_scan++;
   3132   }
   3133 }
   3134 void _CompositeRow_Argb2Argb_RgbByteOrder(uint8_t* dest_scan,
   3135                                           const uint8_t* src_scan,
   3136                                           int pixel_count,
   3137                                           int blend_type,
   3138                                           const uint8_t* clip_scan) {
   3139   int blended_colors[3];
   3140   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   3141   for (int col = 0; col < pixel_count; col++) {
   3142     uint8_t back_alpha = dest_scan[3];
   3143     if (back_alpha == 0) {
   3144       if (clip_scan) {
   3145         int src_alpha = clip_scan[col] * src_scan[3] / 255;
   3146         dest_scan[3] = src_alpha;
   3147         dest_scan[0] = src_scan[2];
   3148         dest_scan[1] = src_scan[1];
   3149         dest_scan[2] = src_scan[0];
   3150       } else {
   3151         FXARGB_RGBORDERCOPY(dest_scan, src_scan);
   3152       }
   3153       dest_scan += 4;
   3154       src_scan += 4;
   3155       continue;
   3156     }
   3157     uint8_t src_alpha;
   3158     if (clip_scan) {
   3159       src_alpha = clip_scan[col] * src_scan[3] / 255;
   3160     } else {
   3161       src_alpha = src_scan[3];
   3162     }
   3163     if (src_alpha == 0) {
   3164       dest_scan += 4;
   3165       src_scan += 4;
   3166       continue;
   3167     }
   3168     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   3169     dest_scan[3] = dest_alpha;
   3170     int alpha_ratio = src_alpha * 255 / dest_alpha;
   3171     if (bNonseparableBlend) {
   3172       uint8_t dest_scan_o[3];
   3173       dest_scan_o[0] = dest_scan[2];
   3174       dest_scan_o[1] = dest_scan[1];
   3175       dest_scan_o[2] = dest_scan[0];
   3176       _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
   3177     }
   3178     for (int color = 0; color < 3; color++) {
   3179       int index = 2 - color;
   3180       if (blend_type) {
   3181         int blended = bNonseparableBlend
   3182                           ? blended_colors[color]
   3183                           : _BLEND(blend_type, dest_scan[index], *src_scan);
   3184         blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
   3185         dest_scan[index] =
   3186             FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
   3187       } else {
   3188         dest_scan[index] =
   3189             FXDIB_ALPHA_MERGE(dest_scan[index], *src_scan, alpha_ratio);
   3190       }
   3191       src_scan++;
   3192     }
   3193     dest_scan += 4;
   3194     src_scan++;
   3195   }
   3196 }
   3197 void _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(uint8_t* dest_scan,
   3198                                                       const uint8_t* src_scan,
   3199                                                       int width,
   3200                                                       int blend_type,
   3201                                                       int src_Bpp) {
   3202   int blended_colors[3];
   3203   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   3204   int src_gap = src_Bpp - 3;
   3205   for (int col = 0; col < width; col++) {
   3206     uint8_t back_alpha = dest_scan[3];
   3207     if (back_alpha == 0) {
   3208       if (src_Bpp == 4) {
   3209         FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
   3210       } else {
   3211         FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2],
   3212                                                      src_scan[1], src_scan[0]));
   3213       }
   3214       dest_scan += 4;
   3215       src_scan += src_Bpp;
   3216       continue;
   3217     }
   3218     dest_scan[3] = 0xff;
   3219     if (bNonseparableBlend) {
   3220       uint8_t dest_scan_o[3];
   3221       dest_scan_o[0] = dest_scan[2];
   3222       dest_scan_o[1] = dest_scan[1];
   3223       dest_scan_o[2] = dest_scan[0];
   3224       _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
   3225     }
   3226     for (int color = 0; color < 3; color++) {
   3227       int index = 2 - color;
   3228       int src_color = FX_GAMMA(*src_scan);
   3229       int blended = bNonseparableBlend
   3230                         ? blended_colors[color]
   3231                         : _BLEND(blend_type, dest_scan[index], src_color);
   3232       dest_scan[index] = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
   3233       src_scan++;
   3234     }
   3235     dest_scan += 4;
   3236     src_scan += src_gap;
   3237   }
   3238 }
   3239 inline void _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(
   3240     uint8_t* dest_scan,
   3241     const uint8_t* src_scan,
   3242     int width,
   3243     int blend_type,
   3244     int dest_Bpp,
   3245     const uint8_t* clip_scan) {
   3246   int blended_colors[3];
   3247   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   3248   for (int col = 0; col < width; col++) {
   3249     uint8_t src_alpha;
   3250     if (clip_scan) {
   3251       src_alpha = src_scan[3] * (*clip_scan++) / 255;
   3252     } else {
   3253       src_alpha = src_scan[3];
   3254     }
   3255     if (src_alpha == 0) {
   3256       dest_scan += dest_Bpp;
   3257       src_scan += 4;
   3258       continue;
   3259     }
   3260     if (bNonseparableBlend) {
   3261       uint8_t dest_scan_o[3];
   3262       dest_scan_o[0] = dest_scan[2];
   3263       dest_scan_o[1] = dest_scan[1];
   3264       dest_scan_o[2] = dest_scan[0];
   3265       _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
   3266     }
   3267     for (int color = 0; color < 3; color++) {
   3268       int index = 2 - color;
   3269       int back_color = FX_GAMMA(dest_scan[index]);
   3270       int blended = bNonseparableBlend
   3271                         ? blended_colors[color]
   3272                         : _BLEND(blend_type, back_color, *src_scan);
   3273       dest_scan[index] =
   3274           FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
   3275       src_scan++;
   3276     }
   3277     dest_scan += dest_Bpp;
   3278     src_scan++;
   3279   }
   3280 }
   3281 inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(
   3282     uint8_t* dest_scan,
   3283     const uint8_t* src_scan,
   3284     int width,
   3285     int src_Bpp) {
   3286   for (int col = 0; col < width; col++) {
   3287     if (src_Bpp == 4) {
   3288       FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
   3289     } else {
   3290       FXARGB_SETRGBORDERDIB(
   3291           dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
   3292     }
   3293     dest_scan += 4;
   3294     src_scan += src_Bpp;
   3295   }
   3296 }
   3297 inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(
   3298     uint8_t* dest_scan,
   3299     const uint8_t* src_scan,
   3300     int width,
   3301     int blend_type,
   3302     int dest_Bpp,
   3303     int src_Bpp) {
   3304   int blended_colors[3];
   3305   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   3306   int src_gap = src_Bpp - 3;
   3307   for (int col = 0; col < width; col++) {
   3308     if (bNonseparableBlend) {
   3309       uint8_t dest_scan_o[3];
   3310       dest_scan_o[0] = dest_scan[2];
   3311       dest_scan_o[1] = dest_scan[1];
   3312       dest_scan_o[2] = dest_scan[0];
   3313       _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
   3314     }
   3315     for (int color = 0; color < 3; color++) {
   3316       int index = 2 - color;
   3317       int back_color = FX_GAMMA(dest_scan[index]);
   3318       int src_color = FX_GAMMA(*src_scan);
   3319       int blended = bNonseparableBlend
   3320                         ? blended_colors[color]
   3321                         : _BLEND(blend_type, back_color, src_color);
   3322       dest_scan[index] = FX_GAMMA_INVERSE(blended);
   3323       src_scan++;
   3324     }
   3325     dest_scan += dest_Bpp;
   3326     src_scan += src_gap;
   3327   }
   3328 }
   3329 inline void _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(
   3330     uint8_t* dest_scan,
   3331     const uint8_t* src_scan,
   3332     int width,
   3333     int dest_Bpp,
   3334     const uint8_t* clip_scan) {
   3335   for (int col = 0; col < width; col++) {
   3336     uint8_t src_alpha;
   3337     if (clip_scan) {
   3338       src_alpha = src_scan[3] * (*clip_scan++) / 255;
   3339     } else {
   3340       src_alpha = src_scan[3];
   3341     }
   3342     if (src_alpha == 255) {
   3343       dest_scan[2] = FX_GAMMA_INVERSE(*src_scan++);
   3344       dest_scan[1] = FX_GAMMA_INVERSE(*src_scan++);
   3345       dest_scan[0] = FX_GAMMA_INVERSE(*src_scan++);
   3346       dest_scan += dest_Bpp;
   3347       src_scan++;
   3348       continue;
   3349     }
   3350     if (src_alpha == 0) {
   3351       dest_scan += dest_Bpp;
   3352       src_scan += 4;
   3353       continue;
   3354     }
   3355     for (int color = 0; color < 3; color++) {
   3356       int index = 2 - color;
   3357       dest_scan[index] = FX_GAMMA_INVERSE(
   3358           FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[index]), *src_scan, src_alpha));
   3359       src_scan++;
   3360     }
   3361     dest_scan += dest_Bpp;
   3362     src_scan++;
   3363   }
   3364 }
   3365 inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(
   3366     uint8_t* dest_scan,
   3367     const uint8_t* src_scan,
   3368     int width,
   3369     int dest_Bpp,
   3370     int src_Bpp) {
   3371   for (int col = 0; col < width; col++) {
   3372     dest_scan[2] = src_scan[0];
   3373     dest_scan[1] = src_scan[1];
   3374     dest_scan[0] = src_scan[2];
   3375     dest_scan += dest_Bpp;
   3376     src_scan += src_Bpp;
   3377   }
   3378 }
   3379 inline void _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(
   3380     uint8_t* dest_scan,
   3381     const uint8_t* src_scan,
   3382     int width,
   3383     int blend_type,
   3384     int src_Bpp,
   3385     const uint8_t* clip_scan) {
   3386   int blended_colors[3];
   3387   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   3388   int src_gap = src_Bpp - 3;
   3389   for (int col = 0; col < width; col++) {
   3390     int src_alpha = *clip_scan++;
   3391     uint8_t back_alpha = dest_scan[3];
   3392     if (back_alpha == 0) {
   3393       dest_scan[2] = FX_GAMMA(*src_scan++);
   3394       dest_scan[1] = FX_GAMMA(*src_scan++);
   3395       dest_scan[0] = FX_GAMMA(*src_scan++);
   3396       src_scan += src_gap;
   3397       dest_scan += 4;
   3398       continue;
   3399     }
   3400     if (src_alpha == 0) {
   3401       dest_scan += 4;
   3402       src_scan += src_Bpp;
   3403       continue;
   3404     }
   3405     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   3406     dest_scan[3] = dest_alpha;
   3407     int alpha_ratio = src_alpha * 255 / dest_alpha;
   3408     if (bNonseparableBlend) {
   3409       uint8_t dest_scan_o[3];
   3410       dest_scan_o[0] = dest_scan[2];
   3411       dest_scan_o[1] = dest_scan[1];
   3412       dest_scan_o[2] = dest_scan[0];
   3413       _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
   3414     }
   3415     for (int color = 0; color < 3; color++) {
   3416       int index = 2 - color;
   3417       int src_color = FX_GAMMA(*src_scan);
   3418       int blended = bNonseparableBlend
   3419                         ? blended_colors[color]
   3420                         : _BLEND(blend_type, dest_scan[index], src_color);
   3421       blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
   3422       dest_scan[index] =
   3423           FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
   3424       src_scan++;
   3425     }
   3426     dest_scan += 4;
   3427     src_scan += src_gap;
   3428   }
   3429 }
   3430 inline void _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(
   3431     uint8_t* dest_scan,
   3432     const uint8_t* src_scan,
   3433     int width,
   3434     int blend_type,
   3435     int dest_Bpp,
   3436     int src_Bpp,
   3437     const uint8_t* clip_scan) {
   3438   int blended_colors[3];
   3439   FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
   3440   int src_gap = src_Bpp - 3;
   3441   for (int col = 0; col < width; col++) {
   3442     uint8_t src_alpha = *clip_scan++;
   3443     if (src_alpha == 0) {
   3444       dest_scan += dest_Bpp;
   3445       src_scan += src_Bpp;
   3446       continue;
   3447     }
   3448     if (bNonseparableBlend) {
   3449       uint8_t dest_scan_o[3];
   3450       dest_scan_o[0] = dest_scan[2];
   3451       dest_scan_o[1] = dest_scan[1];
   3452       dest_scan_o[2] = dest_scan[0];
   3453       _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
   3454     }
   3455     for (int color = 0; color < 3; color++) {
   3456       int index = 2 - color;
   3457       int src_color = FX_GAMMA(*src_scan);
   3458       int back_color = FX_GAMMA(dest_scan[index]);
   3459       int blended = bNonseparableBlend
   3460                         ? blended_colors[color]
   3461                         : _BLEND(blend_type, back_color, src_color);
   3462       dest_scan[index] =
   3463           FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
   3464       src_scan++;
   3465     }
   3466     dest_scan += dest_Bpp;
   3467     src_scan += src_gap;
   3468   }
   3469 }
   3470 inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(
   3471     uint8_t* dest_scan,
   3472     const uint8_t* src_scan,
   3473     int width,
   3474     int src_Bpp,
   3475     const uint8_t* clip_scan) {
   3476   int src_gap = src_Bpp - 3;
   3477   for (int col = 0; col < width; col++) {
   3478     int src_alpha = clip_scan[col];
   3479     if (src_alpha == 255) {
   3480       dest_scan[2] = FX_GAMMA(*src_scan++);
   3481       dest_scan[1] = FX_GAMMA(*src_scan++);
   3482       dest_scan[0] = FX_GAMMA(*src_scan++);
   3483       dest_scan[3] = 255;
   3484       dest_scan += 4;
   3485       src_scan += src_gap;
   3486       continue;
   3487     }
   3488     if (src_alpha == 0) {
   3489       dest_scan += 4;
   3490       src_scan += src_Bpp;
   3491       continue;
   3492     }
   3493     int back_alpha = dest_scan[3];
   3494     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   3495     dest_scan[3] = dest_alpha;
   3496     int alpha_ratio = src_alpha * 255 / dest_alpha;
   3497     for (int color = 0; color < 3; color++) {
   3498       int index = 2 - color;
   3499       dest_scan[index] =
   3500           FXDIB_ALPHA_MERGE(dest_scan[index], FX_GAMMA(*src_scan), alpha_ratio);
   3501       src_scan++;
   3502     }
   3503     dest_scan += 4;
   3504     src_scan += src_gap;
   3505   }
   3506 }
   3507 inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(
   3508     uint8_t* dest_scan,
   3509     const uint8_t* src_scan,
   3510     int width,
   3511     int dest_Bpp,
   3512     int src_Bpp,
   3513     const uint8_t* clip_scan) {
   3514   for (int col = 0; col < width; col++) {
   3515     int src_alpha = clip_scan[col];
   3516     if (src_alpha == 255) {
   3517       dest_scan[2] = src_scan[0];
   3518       dest_scan[1] = src_scan[1];
   3519       dest_scan[0] = src_scan[2];
   3520     } else if (src_alpha) {
   3521       dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
   3522           FX_GAMMA(dest_scan[2]), FX_GAMMA(*src_scan), src_alpha));
   3523       src_scan++;
   3524       dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
   3525           FX_GAMMA(dest_scan[1]), FX_GAMMA(*src_scan), src_alpha));
   3526       src_scan++;
   3527       dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
   3528           FX_GAMMA(dest_scan[0]), FX_GAMMA(*src_scan), src_alpha));
   3529       dest_scan += dest_Bpp;
   3530       src_scan += src_Bpp - 2;
   3531       continue;
   3532     }
   3533     dest_scan += dest_Bpp;
   3534     src_scan += src_Bpp;
   3535   }
   3536 }
   3537 inline void _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(
   3538     uint8_t* dest_scan,
   3539     const uint8_t* src_scan,
   3540     FX_ARGB* pPalette,
   3541     int pixel_count,
   3542     int DestBpp,
   3543     const uint8_t* clip_scan) {
   3544   for (int col = 0; col < pixel_count; col++) {
   3545     FX_ARGB argb = pPalette ? pPalette[*src_scan] : (*src_scan) * 0x010101;
   3546     int src_r = FXARGB_R(argb);
   3547     int src_g = FXARGB_G(argb);
   3548     int src_b = FXARGB_B(argb);
   3549     if (clip_scan && clip_scan[col] < 255) {
   3550       dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
   3551       dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
   3552       dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
   3553     } else {
   3554       dest_scan[2] = src_b;
   3555       dest_scan[1] = src_g;
   3556       dest_scan[0] = src_r;
   3557     }
   3558     dest_scan += DestBpp;
   3559     src_scan++;
   3560   }
   3561 }
   3562 inline void _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(
   3563     uint8_t* dest_scan,
   3564     const uint8_t* src_scan,
   3565     int src_left,
   3566     FX_ARGB* pPalette,
   3567     int pixel_count,
   3568     int DestBpp,
   3569     const uint8_t* clip_scan) {
   3570   int reset_r, reset_g, reset_b;
   3571   int set_r, set_g, set_b;
   3572   if (pPalette) {
   3573     reset_r = FXARGB_R(pPalette[0]);
   3574     reset_g = FXARGB_G(pPalette[0]);
   3575     reset_b = FXARGB_B(pPalette[0]);
   3576     set_r = FXARGB_R(pPalette[1]);
   3577     set_g = FXARGB_G(pPalette[1]);
   3578     set_b = FXARGB_B(pPalette[1]);
   3579   } else {
   3580     reset_r = reset_g = reset_b = 0;
   3581     set_r = set_g = set_b = 255;
   3582   }
   3583   for (int col = 0; col < pixel_count; col++) {
   3584     int src_r, src_g, src_b;
   3585     if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
   3586       src_r = set_r;
   3587       src_g = set_g;
   3588       src_b = set_b;
   3589     } else {
   3590       src_r = reset_r;
   3591       src_g = reset_g;
   3592       src_b = reset_b;
   3593     }
   3594     if (clip_scan && clip_scan[col] < 255) {
   3595       dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
   3596       dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
   3597       dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
   3598     } else {
   3599       dest_scan[2] = src_b;
   3600       dest_scan[1] = src_g;
   3601       dest_scan[0] = src_r;
   3602     }
   3603     dest_scan += DestBpp;
   3604   }
   3605 }
   3606 inline void _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(
   3607     uint8_t* dest_scan,
   3608     const uint8_t* src_scan,
   3609     int width,
   3610     FX_ARGB* pPalette,
   3611     const uint8_t* clip_scan) {
   3612   for (int col = 0; col < width; col++) {
   3613     int src_r, src_g, src_b;
   3614     if (pPalette) {
   3615       FX_ARGB argb = pPalette[*src_scan];
   3616       src_r = FXARGB_R(argb);
   3617       src_g = FXARGB_G(argb);
   3618       src_b = FXARGB_B(argb);
   3619     } else {
   3620       src_r = src_g = src_b = *src_scan;
   3621     }
   3622     if (!clip_scan || clip_scan[col] == 255) {
   3623       dest_scan[2] = FX_GAMMA(src_b);
   3624       dest_scan[1] = FX_GAMMA(src_g);
   3625       dest_scan[0] = FX_GAMMA(src_r);
   3626       dest_scan[3] = 255;
   3627       src_scan++;
   3628       dest_scan += 4;
   3629       continue;
   3630     }
   3631     int src_alpha = clip_scan[col];
   3632     if (src_alpha == 0) {
   3633       dest_scan += 4;
   3634       src_scan++;
   3635       continue;
   3636     }
   3637     int back_alpha = dest_scan[3];
   3638     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   3639     dest_scan[3] = dest_alpha;
   3640     int alpha_ratio = src_alpha * 255 / dest_alpha;
   3641     dest_scan[2] =
   3642         FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
   3643     dest_scan[1] =
   3644         FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
   3645     dest_scan[0] =
   3646         FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
   3647     dest_scan += 4;
   3648     src_scan++;
   3649   }
   3650 }
   3651 inline void _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(
   3652     uint8_t* dest_scan,
   3653     const uint8_t* src_scan,
   3654     int src_left,
   3655     int width,
   3656     FX_ARGB* pPalette,
   3657     const uint8_t* clip_scan) {
   3658   int reset_r, reset_g, reset_b;
   3659   int set_r, set_g, set_b;
   3660   if (pPalette) {
   3661     reset_r = FXARGB_R(pPalette[0]);
   3662     reset_g = FXARGB_G(pPalette[0]);
   3663     reset_b = FXARGB_B(pPalette[0]);
   3664     set_r = FXARGB_R(pPalette[1]);
   3665     set_g = FXARGB_G(pPalette[1]);
   3666     set_b = FXARGB_B(pPalette[1]);
   3667   } else {
   3668     reset_r = reset_g = reset_b = 0;
   3669     set_r = set_g = set_b = 255;
   3670   }
   3671   for (int col = 0; col < width; col++) {
   3672     int src_r, src_g, src_b;
   3673     if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
   3674       src_r = set_r;
   3675       src_g = set_g;
   3676       src_b = set_b;
   3677     } else {
   3678       src_r = reset_r;
   3679       src_g = reset_g;
   3680       src_b = reset_b;
   3681     }
   3682     if (!clip_scan || clip_scan[col] == 255) {
   3683       dest_scan[2] = FX_GAMMA(src_b);
   3684       dest_scan[1] = FX_GAMMA(src_g);
   3685       dest_scan[0] = FX_GAMMA(src_r);
   3686       dest_scan[3] = 255;
   3687       dest_scan += 4;
   3688       continue;
   3689     }
   3690     int src_alpha = clip_scan[col];
   3691     if (src_alpha == 0) {
   3692       dest_scan += 4;
   3693       continue;
   3694     }
   3695     int back_alpha = dest_scan[3];
   3696     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   3697     dest_scan[3] = dest_alpha;
   3698     int alpha_ratio = src_alpha * 255 / dest_alpha;
   3699     dest_scan[2] =
   3700         FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
   3701     dest_scan[1] =
   3702         FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
   3703     dest_scan[0] =
   3704         FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
   3705     dest_scan += 4;
   3706   }
   3707 }
   3708 void _CompositeRow_ByteMask2Argb_RgbByteOrder(uint8_t* dest_scan,
   3709                                               const uint8_t* src_scan,
   3710                                               int mask_alpha,
   3711                                               int src_r,
   3712                                               int src_g,
   3713                                               int src_b,
   3714                                               int pixel_count,
   3715                                               int blend_type,
   3716                                               const uint8_t* clip_scan) {
   3717   for (int col = 0; col < pixel_count; col++) {
   3718     int src_alpha;
   3719     if (clip_scan) {
   3720       src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
   3721     } else {
   3722       src_alpha = mask_alpha * src_scan[col] / 255;
   3723     }
   3724     uint8_t back_alpha = dest_scan[3];
   3725     if (back_alpha == 0) {
   3726       FXARGB_SETRGBORDERDIB(dest_scan,
   3727                             FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
   3728       dest_scan += 4;
   3729       continue;
   3730     }
   3731     if (src_alpha == 0) {
   3732       dest_scan += 4;
   3733       continue;
   3734     }
   3735     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   3736     dest_scan[3] = dest_alpha;
   3737     int alpha_ratio = src_alpha * 255 / dest_alpha;
   3738     if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
   3739       int blended_colors[3];
   3740       uint8_t src_scan[3];
   3741       uint8_t dest_scan_o[3];
   3742       src_scan[0] = src_b;
   3743       src_scan[1] = src_g;
   3744       src_scan[2] = src_r;
   3745       dest_scan_o[0] = dest_scan[2];
   3746       dest_scan_o[1] = dest_scan[1];
   3747       dest_scan_o[2] = dest_scan[0];
   3748       _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
   3749       dest_scan[2] =
   3750           FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
   3751       dest_scan[1] =
   3752           FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
   3753       dest_scan[0] =
   3754           FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
   3755     } else if (blend_type) {
   3756       int blended = _BLEND(blend_type, dest_scan[2], src_b);
   3757       blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
   3758       dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
   3759       blended = _BLEND(blend_type, dest_scan[1], src_g);
   3760       blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
   3761       dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
   3762       blended = _BLEND(blend_type, dest_scan[0], src_r);
   3763       blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
   3764       dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
   3765     } else {
   3766       dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
   3767       dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
   3768       dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
   3769     }
   3770     dest_scan += 4;
   3771   }
   3772 }
   3773 void _CompositeRow_ByteMask2Rgb_RgbByteOrder(uint8_t* dest_scan,
   3774                                              const uint8_t* src_scan,
   3775                                              int mask_alpha,
   3776                                              int src_r,
   3777                                              int src_g,
   3778                                              int src_b,
   3779                                              int pixel_count,
   3780                                              int blend_type,
   3781                                              int Bpp,
   3782                                              const uint8_t* clip_scan) {
   3783   for (int col = 0; col < pixel_count; col++) {
   3784     int src_alpha;
   3785     if (clip_scan) {
   3786       src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
   3787     } else {
   3788       src_alpha = mask_alpha * src_scan[col] / 255;
   3789     }
   3790     if (src_alpha == 0) {
   3791       dest_scan += Bpp;
   3792       continue;
   3793     }
   3794     if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
   3795       int blended_colors[3];
   3796       uint8_t src_scan[3];
   3797       uint8_t dest_scan_o[3];
   3798       src_scan[0] = src_b;
   3799       src_scan[1] = src_g;
   3800       src_scan[2] = src_r;
   3801       dest_scan_o[0] = dest_scan[2];
   3802       dest_scan_o[1] = dest_scan[1];
   3803       dest_scan_o[2] = dest_scan[0];
   3804       _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
   3805       dest_scan[2] =
   3806           FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
   3807       dest_scan[1] =
   3808           FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
   3809       dest_scan[0] =
   3810           FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
   3811     } else if (blend_type) {
   3812       int blended = _BLEND(blend_type, dest_scan[2], src_b);
   3813       dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, src_alpha);
   3814       blended = _BLEND(blend_type, dest_scan[1], src_g);
   3815       dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, src_alpha);
   3816       blended = _BLEND(blend_type, dest_scan[0], src_r);
   3817       dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, src_alpha);
   3818     } else {
   3819       dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, src_alpha);
   3820       dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, src_alpha);
   3821       dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, src_alpha);
   3822     }
   3823     dest_scan += Bpp;
   3824   }
   3825 }
   3826 void _CompositeRow_BitMask2Argb_RgbByteOrder(uint8_t* dest_scan,
   3827                                              const uint8_t* src_scan,
   3828                                              int mask_alpha,
   3829                                              int src_r,
   3830                                              int src_g,
   3831                                              int src_b,
   3832                                              int src_left,
   3833                                              int pixel_count,
   3834                                              int blend_type,
   3835                                              const uint8_t* clip_scan) {
   3836   if (blend_type == FXDIB_BLEND_NORMAL && !clip_scan && mask_alpha == 255) {
   3837     FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
   3838     for (int col = 0; col < pixel_count; col++) {
   3839       if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
   3840         FXARGB_SETRGBORDERDIB(dest_scan, argb);
   3841       }
   3842       dest_scan += 4;
   3843     }
   3844     return;
   3845   }
   3846   for (int col = 0; col < pixel_count; col++) {
   3847     if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
   3848       dest_scan += 4;
   3849       continue;
   3850     }
   3851     int src_alpha;
   3852     if (clip_scan) {
   3853       src_alpha = mask_alpha * clip_scan[col] / 255;
   3854     } else {
   3855       src_alpha = mask_alpha;
   3856     }
   3857     uint8_t back_alpha = dest_scan[3];
   3858     if (back_alpha == 0) {
   3859       FXARGB_SETRGBORDERDIB(dest_scan,
   3860                             FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
   3861       dest_scan += 4;
   3862       continue;
   3863     }
   3864     uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
   3865     dest_scan[3] = dest_alpha;
   3866     int alpha_ratio = src_alpha * 255 / dest_alpha;
   3867     if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
   3868       int blended_colors[3];
   3869       uint8_t src_scan[3];
   3870       uint8_t dest_scan_o[3];
   3871       src_scan[0] = src_b;
   3872       src_scan[1] = src_g;
   3873       src_scan[2] = src_r;
   3874       dest_scan_o[0] = dest_scan[2];
   3875       dest_scan_o[1] = dest_scan[1];
   3876       dest_scan_o[2] = dest_scan[0];
   3877       _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
   3878       dest_scan[2] =
   3879           FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
   3880       dest_scan[1] =
   3881           FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
   3882       dest_scan[0] =
   3883           FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
   3884     } else if (blend_type) {
   3885       int blended = _BLEND(blend_type, dest_scan[2], src_b);
   3886       blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
   3887       dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
   3888       blended = _BLEND(blend_type, dest_scan[1], src_g);
   3889       blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
   3890       dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
   3891       blended = _BLEND(blend_type, dest_scan[0], src_r);
   3892       blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
   3893       dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
   3894     } else {
   3895       dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
   3896       dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
   3897       dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
   3898     }
   3899     dest_scan += 4;
   3900   }
   3901 }
   3902 void _CompositeRow_BitMask2Rgb_RgbByteOrder(uint8_t* dest_scan,
   3903                                             const uint8_t* src_scan,
   3904                                             int mask_alpha,
   3905                                             int src_r,
   3906                                             int src_g,
   3907                                             int src_b,
   3908                                             int src_left,
   3909                                             int pixel_count,
   3910                                             int blend_type,
   3911                                             int Bpp,
   3912                                             const uint8_t* clip_scan) {
   3913   if (blend_type == FXDIB_BLEND_NORMAL && !clip_scan && mask_alpha == 255) {
   3914     for (int col = 0; col < pixel_count; col++) {
   3915       if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
   3916         dest_scan[2] = src_b;
   3917         dest_scan[1] = src_g;
   3918         dest_scan[0] = src_r;
   3919       }
   3920       dest_scan += Bpp;
   3921     }
   3922     return;
   3923   }
   3924   for (int col = 0; col < pixel_count; col++) {
   3925     if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
   3926       dest_scan += Bpp;
   3927       continue;
   3928     }
   3929     int src_alpha;
   3930     if (clip_scan) {
   3931       src_alpha = mask_alpha * clip_scan[col] / 255;
   3932     } else {
   3933       src_alpha = mask_alpha;
   3934     }
   3935     if (src_alpha == 0) {
   3936       dest_scan += Bpp;
   3937       continue;
   3938     }
   3939     if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
   3940       int blended_colors[3];
   3941       uint8_t src_scan[3];
   3942       uint8_t dest_scan_o[3];
   3943       src_scan[0] = src_b;
   3944       src_scan[1] = src_g;
   3945       src_scan[2] = src_r;
   3946       dest_scan_o[0] = dest_scan[2];
   3947       dest_scan_o[1] = dest_scan[1];
   3948       dest_scan_o[2] = dest_scan[0];
   3949       _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
   3950       dest_scan[2] =
   3951           FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
   3952       dest_scan[1] =
   3953           FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
   3954       dest_scan[0] =
   3955           FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
   3956     } else if (blend_type) {
   3957       int back_color = FX_GAMMA(dest_scan[2]);
   3958       int blended = _BLEND(blend_type, back_color, src_b);
   3959       dest_scan[2] =
   3960           FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
   3961       back_color = FX_GAMMA(dest_scan[1]);
   3962       blended = _BLEND(blend_type, back_color, src_g);
   3963       dest_scan[1] =
   3964           FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
   3965       back_color = FX_GAMMA(dest_scan[0]);
   3966       blended = _BLEND(blend_type, back_color, src_r);
   3967       dest_scan[0] =
   3968           FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
   3969     } else {
   3970       dest_scan[2] = FX_GAMMA_INVERSE(
   3971           FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), src_b, src_alpha));
   3972       dest_scan[1] = FX_GAMMA_INVERSE(
   3973           FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), src_g, src_alpha));
   3974       dest_scan[0] = FX_GAMMA_INVERSE(
   3975           FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), src_r, src_alpha));
   3976     }
   3977     dest_scan += Bpp;
   3978   }
   3979 }
   3980 inline FX_BOOL _ScanlineCompositor_InitSourceMask(FXDIB_Format dest_format,
   3981                                                   int alpha_flag,
   3982                                                   FX_DWORD mask_color,
   3983                                                   int& mask_alpha,
   3984                                                   int& mask_red,
   3985                                                   int& mask_green,
   3986                                                   int& mask_blue,
   3987                                                   int& mask_black,
   3988                                                   void* icc_module,
   3989                                                   void* pIccTransform) {
   3990   ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
   3991   if (alpha_flag >> 8) {
   3992     mask_alpha = alpha_flag & 0xff;
   3993     mask_red = FXSYS_GetCValue(mask_color);
   3994     mask_green = FXSYS_GetMValue(mask_color);
   3995     mask_blue = FXSYS_GetYValue(mask_color);
   3996     mask_black = FXSYS_GetKValue(mask_color);
   3997   } else {
   3998     mask_alpha = FXARGB_A(mask_color);
   3999     mask_red = FXARGB_R(mask_color);
   4000     mask_green = FXARGB_G(mask_color);
   4001     mask_blue = FXARGB_B(mask_color);
   4002   }
   4003   if (dest_format == FXDIB_8bppMask) {
   4004     return TRUE;
   4005   }
   4006   if ((dest_format & 0xff) == 8) {
   4007     if (pIccTransform) {
   4008       mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color)
   4009                                      : FXARGB_TODIB(mask_color);
   4010       uint8_t* gray_p = (uint8_t*)&mask_color;
   4011       pIccModule->TranslateScanline(pIccTransform, gray_p, gray_p, 1);
   4012       mask_red = dest_format & 0x0400 ? FX_CCOLOR(gray_p[0]) : gray_p[0];
   4013     } else {
   4014       if (alpha_flag >> 8) {
   4015         uint8_t r, g, b;
   4016         AdobeCMYK_to_sRGB1(mask_red, mask_green, mask_blue, mask_black, r, g,
   4017                            b);
   4018         mask_red = FXRGB2GRAY(r, g, b);
   4019       } else {
   4020         mask_red = FXRGB2GRAY(mask_red, mask_green, mask_blue);
   4021       }
   4022       if (dest_format & 0x0400) {
   4023         mask_red = FX_CCOLOR(mask_red);
   4024       }
   4025     }
   4026   } else {
   4027     uint8_t* mask_color_p = (uint8_t*)&mask_color;
   4028     mask_color =
   4029         (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color);
   4030     if (pIccTransform) {
   4031       pIccModule->TranslateScanline(pIccTransform, mask_color_p, mask_color_p,
   4032                                     1);
   4033       mask_red = mask_color_p[2];
   4034       mask_green = mask_color_p[1];
   4035       mask_blue = mask_color_p[0];
   4036     } else if (alpha_flag >> 8) {
   4037       AdobeCMYK_to_sRGB1(mask_color_p[0], mask_color_p[1], mask_color_p[2],
   4038                          mask_color_p[3], mask_color_p[2], mask_color_p[1],
   4039                          mask_color_p[0]);
   4040       mask_red = mask_color_p[2];
   4041       mask_green = mask_color_p[1];
   4042       mask_blue = mask_color_p[0];
   4043     }
   4044   }
   4045   return TRUE;
   4046 }
   4047 inline void _ScanlineCompositor_InitSourcePalette(FXDIB_Format src_format,
   4048                                                   FXDIB_Format dest_format,
   4049                                                   FX_DWORD*& pDestPalette,
   4050                                                   FX_DWORD* pSrcPalette,
   4051                                                   void* icc_module,
   4052                                                   void* pIccTransform) {
   4053   ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
   4054   FX_BOOL isSrcCmyk = !!(src_format & 0x0400);
   4055   FX_BOOL isDstCmyk = !!(dest_format & 0x0400);
   4056   pDestPalette = NULL;
   4057   if (pIccTransform) {
   4058     if (pSrcPalette) {
   4059       if ((dest_format & 0xff) == 8) {
   4060         int pal_count = 1 << (src_format & 0xff);
   4061         uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count);
   4062         pDestPalette = (FX_DWORD*)gray_pal;
   4063         for (int i = 0; i < pal_count; i++) {
   4064           FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i])
   4065                                      : FXARGB_TODIB(pSrcPalette[i]);
   4066           pIccModule->TranslateScanline(pIccTransform, gray_pal,
   4067                                         (const uint8_t*)&color, 1);
   4068           gray_pal++;
   4069         }
   4070       } else {
   4071         int palsize = 1 << (src_format & 0xff);
   4072         pDestPalette = FX_Alloc(FX_DWORD, palsize);
   4073         for (int i = 0; i < palsize; i++) {
   4074           FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i])
   4075                                      : FXARGB_TODIB(pSrcPalette[i]);
   4076           pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&color,
   4077                                         (const uint8_t*)&color, 1);
   4078           pDestPalette[i] =
   4079               isDstCmyk ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
   4080         }
   4081       }
   4082     } else {
   4083       int pal_count = 1 << (src_format & 0xff);
   4084       uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count);
   4085       if (pal_count == 2) {
   4086         gray_pal[0] = 0;
   4087         gray_pal[1] = 255;
   4088       } else {
   4089         for (int i = 0; i < pal_count; i++) {
   4090           gray_pal[i] = i;
   4091         }
   4092       }
   4093       if ((dest_format & 0xff) == 8) {
   4094         pIccModule->TranslateScanline(pIccTransform, gray_pal, gray_pal,
   4095                                       pal_count);
   4096         pDestPalette = (FX_DWORD*)gray_pal;
   4097       } else {
   4098         pDestPalette = FX_Alloc(FX_DWORD, pal_count);
   4099         for (int i = 0; i < pal_count; i++) {
   4100           pIccModule->TranslateScanline(
   4101               pIccTransform, (uint8_t*)&pDestPalette[i], &gray_pal[i], 1);
   4102           pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(pDestPalette[i])
   4103                                       : FXARGB_TODIB(pDestPalette[i]);
   4104         }
   4105         FX_Free(gray_pal);
   4106       }
   4107     }
   4108   } else {
   4109     if (pSrcPalette) {
   4110       if ((dest_format & 0xff) == 8) {
   4111         int pal_count = 1 << (src_format & 0xff);
   4112         uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count);
   4113         pDestPalette = (FX_DWORD*)gray_pal;
   4114         if (isSrcCmyk) {
   4115           for (int i = 0; i < pal_count; i++) {
   4116             FX_CMYK cmyk = pSrcPalette[i];
   4117             uint8_t r, g, b;
   4118             AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk),
   4119                                FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), r,
   4120                                g, b);
   4121             *gray_pal++ = FXRGB2GRAY(r, g, b);
   4122           }
   4123         } else
   4124           for (int i = 0; i < pal_count; i++) {
   4125             FX_ARGB argb = pSrcPalette[i];
   4126             *gray_pal++ =
   4127                 FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
   4128           }
   4129       } else {
   4130         int palsize = 1 << (src_format & 0xff);
   4131         pDestPalette = FX_Alloc(FX_DWORD, palsize);
   4132         if (isDstCmyk == isSrcCmyk) {
   4133           FXSYS_memcpy(pDestPalette, pSrcPalette, palsize * sizeof(FX_DWORD));
   4134         } else {
   4135           for (int i = 0; i < palsize; i++) {
   4136             FX_CMYK cmyk = pSrcPalette[i];
   4137             uint8_t r, g, b;
   4138             AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk),
   4139                                FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), r,
   4140                                g, b);
   4141             pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
   4142           }
   4143         }
   4144       }
   4145     } else {
   4146       if ((dest_format & 0xff) == 8) {
   4147         int pal_count = 1 << (src_format & 0xff);
   4148         uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count);
   4149         if (pal_count == 2) {
   4150           gray_pal[0] = 0;
   4151           gray_pal[1] = 255;
   4152         } else {
   4153           for (int i = 0; i < pal_count; i++) {
   4154             gray_pal[i] = i;
   4155           }
   4156         }
   4157         pDestPalette = (FX_DWORD*)gray_pal;
   4158       } else {
   4159         int palsize = 1 << (src_format & 0xff);
   4160         pDestPalette = FX_Alloc(FX_DWORD, palsize);
   4161         if (palsize == 2) {
   4162           pDestPalette[0] = isSrcCmyk ? 255 : 0xff000000;
   4163           pDestPalette[1] = isSrcCmyk ? 0 : 0xffffffff;
   4164         } else {
   4165           for (int i = 0; i < palsize; i++) {
   4166             pDestPalette[i] = isSrcCmyk ? FX_CCOLOR(i) : (i * 0x10101);
   4167           }
   4168         }
   4169         if (isSrcCmyk != isDstCmyk) {
   4170           for (int i = 0; i < palsize; i++) {
   4171             FX_CMYK cmyk = pDestPalette[i];
   4172             uint8_t r, g, b;
   4173             AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk),
   4174                                FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), r,
   4175                                g, b);
   4176             pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
   4177           }
   4178         }
   4179       }
   4180     }
   4181   }
   4182 }
   4183 CFX_ScanlineCompositor::CFX_ScanlineCompositor() {
   4184   m_pSrcPalette = NULL;
   4185   m_pCacheScanline = NULL;
   4186   m_CacheSize = 0;
   4187   m_bRgbByteOrder = FALSE;
   4188   m_BlendType = FXDIB_BLEND_NORMAL;
   4189 }
   4190 CFX_ScanlineCompositor::~CFX_ScanlineCompositor() {
   4191   FX_Free(m_pSrcPalette);
   4192   FX_Free(m_pCacheScanline);
   4193 }
   4194 FX_BOOL CFX_ScanlineCompositor::Init(FXDIB_Format dest_format,
   4195                                      FXDIB_Format src_format,
   4196                                      int32_t width,
   4197                                      FX_DWORD* pSrcPalette,
   4198                                      FX_DWORD mask_color,
   4199                                      int blend_type,
   4200                                      FX_BOOL bClip,
   4201                                      FX_BOOL bRgbByteOrder,
   4202                                      int alpha_flag,
   4203                                      void* pIccTransform) {
   4204   m_SrcFormat = src_format;
   4205   m_DestFormat = dest_format;
   4206   m_BlendType = blend_type;
   4207   m_bRgbByteOrder = bRgbByteOrder;
   4208   ICodec_IccModule* pIccModule = NULL;
   4209   if (CFX_GEModule::Get()->GetCodecModule()) {
   4210     pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   4211   }
   4212   if (!pIccModule) {
   4213     pIccTransform = NULL;
   4214   }
   4215   m_pIccTransform = pIccTransform;
   4216   if ((dest_format & 0xff) == 1) {
   4217     return FALSE;
   4218   }
   4219   if (m_SrcFormat == FXDIB_1bppMask || m_SrcFormat == FXDIB_8bppMask) {
   4220     return _ScanlineCompositor_InitSourceMask(
   4221         dest_format, alpha_flag, mask_color, m_MaskAlpha, m_MaskRed,
   4222         m_MaskGreen, m_MaskBlue, m_MaskBlack, pIccModule, pIccTransform);
   4223   }
   4224   if (!pIccTransform && (~src_format & 0x0400) && (dest_format & 0x0400)) {
   4225     return FALSE;
   4226   }
   4227   if ((m_SrcFormat & 0xff) <= 8) {
   4228     if (dest_format == FXDIB_8bppMask) {
   4229       return TRUE;
   4230     }
   4231     _ScanlineCompositor_InitSourcePalette(src_format, dest_format,
   4232                                           m_pSrcPalette, pSrcPalette,
   4233                                           pIccModule, pIccTransform);
   4234     m_Transparency =
   4235         (dest_format == FXDIB_Argb ? 1 : 0) + (dest_format & 0x0200 ? 2 : 0) +
   4236         (dest_format & 0x0400 ? 4 : 0) + ((src_format & 0xff) == 1 ? 8 : 0);
   4237     return TRUE;
   4238   }
   4239   m_Transparency = (src_format & 0x0200 ? 0 : 1) +
   4240                    (dest_format & 0x0200 ? 0 : 2) +
   4241                    (blend_type == FXDIB_BLEND_NORMAL ? 4 : 0) +
   4242                    (bClip ? 8 : 0) + (src_format & 0x0400 ? 16 : 0) +
   4243                    (dest_format & 0x0400 ? 32 : 0) + (pIccTransform ? 64 : 0);
   4244   return TRUE;
   4245 }
   4246 void CFX_ScanlineCompositor::CompositeRgbBitmapLine(
   4247     uint8_t* dest_scan,
   4248     const uint8_t* src_scan,
   4249     int width,
   4250     const uint8_t* clip_scan,
   4251     const uint8_t* src_extra_alpha,
   4252     uint8_t* dst_extra_alpha) {
   4253   int src_Bpp = (m_SrcFormat & 0xff) >> 3;
   4254   int dest_Bpp = (m_DestFormat & 0xff) >> 3;
   4255   if (m_bRgbByteOrder) {
   4256     switch (m_Transparency) {
   4257       case 0:
   4258       case 4:
   4259       case 8:
   4260       case 12:
   4261         _CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan, width,
   4262                                              m_BlendType, clip_scan);
   4263         break;
   4264       case 1:
   4265         _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(
   4266             dest_scan, src_scan, width, m_BlendType, src_Bpp);
   4267         break;
   4268       case 2:
   4269       case 10:
   4270         _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(
   4271             dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan);
   4272         break;
   4273       case 3:
   4274         _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(
   4275             dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
   4276         break;
   4277       case 5:
   4278         _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan,
   4279                                                            width, src_Bpp);
   4280         break;
   4281       case 6:
   4282       case 14:
   4283         _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, width,
   4284                                                     dest_Bpp, clip_scan);
   4285         break;
   4286       case 7:
   4287         _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(
   4288             dest_scan, src_scan, width, dest_Bpp, src_Bpp);
   4289         break;
   4290       case 9:
   4291         _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(
   4292             dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan);
   4293         break;
   4294       case 11:
   4295         _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(
   4296             dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp,
   4297             clip_scan);
   4298         break;
   4299       case 13:
   4300         _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(
   4301             dest_scan, src_scan, width, src_Bpp, clip_scan);
   4302         break;
   4303       case 15:
   4304         _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(
   4305             dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
   4306         break;
   4307     }
   4308     return;
   4309   }
   4310   if (m_DestFormat == FXDIB_8bppMask) {
   4311     if (m_SrcFormat & 0x0200) {
   4312       if (m_SrcFormat == FXDIB_Argb) {
   4313         _CompositeRow_Argb2Mask(dest_scan, src_scan, width, clip_scan);
   4314       } else {
   4315         _CompositeRow_Rgba2Mask(dest_scan, src_extra_alpha, width, clip_scan);
   4316       }
   4317     } else {
   4318       _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
   4319     }
   4320   } else if ((m_DestFormat & 0xff) == 8) {
   4321     if (m_DestFormat & 0x0400) {
   4322       for (int i = 0; i < width; i++) {
   4323         *dest_scan = ~*dest_scan;
   4324         dest_scan++;
   4325       }
   4326     }
   4327     if (m_SrcFormat & 0x0200) {
   4328       if (m_DestFormat & 0x0200) {
   4329         _CompositeRow_Argb2Graya(dest_scan, src_scan, width, m_BlendType,
   4330                                  clip_scan, src_extra_alpha, dst_extra_alpha,
   4331                                  m_pIccTransform);
   4332       } else {
   4333         _CompositeRow_Argb2Gray(dest_scan, src_scan, width, m_BlendType,
   4334                                 clip_scan, src_extra_alpha, m_pIccTransform);
   4335       }
   4336     } else {
   4337       if (m_DestFormat & 0x0200) {
   4338         _CompositeRow_Rgb2Graya(dest_scan, src_scan, src_Bpp, width,
   4339                                 m_BlendType, clip_scan, dst_extra_alpha,
   4340                                 m_pIccTransform);
   4341       } else {
   4342         _CompositeRow_Rgb2Gray(dest_scan, src_scan, src_Bpp, width, m_BlendType,
   4343                                clip_scan, m_pIccTransform);
   4344       }
   4345     }
   4346     if (m_DestFormat & 0x0400) {
   4347       for (int i = 0; i < width; i++) {
   4348         *dest_scan = ~*dest_scan;
   4349         dest_scan++;
   4350       }
   4351     }
   4352   } else {
   4353     int dest_Size = width * dest_Bpp + 4;
   4354     if (dest_Size > m_CacheSize) {
   4355       m_pCacheScanline = FX_Realloc(uint8_t, m_pCacheScanline, dest_Size);
   4356       if (!m_pCacheScanline) {
   4357         return;
   4358       }
   4359       m_CacheSize = dest_Size;
   4360     }
   4361     switch (m_Transparency) {
   4362       case 0:
   4363       case 4:
   4364       case 8:
   4365       case 4 + 8: {
   4366         _CompositeRow_Argb2Argb(dest_scan, src_scan, width, m_BlendType,
   4367                                 clip_scan, dst_extra_alpha, src_extra_alpha);
   4368       } break;
   4369       case 64:
   4370       case 4 + 64:
   4371       case 8 + 64:
   4372       case 4 + 8 + 64: {
   4373         _CompositeRow_Argb2Argb_Transform(
   4374             dest_scan, src_scan, width, m_BlendType, clip_scan, dst_extra_alpha,
   4375             src_extra_alpha, m_pCacheScanline, m_pIccTransform);
   4376       } break;
   4377       case 1:
   4378         _CompositeRow_Rgb2Argb_Blend_NoClip(
   4379             dest_scan, src_scan, width, m_BlendType, src_Bpp, dst_extra_alpha);
   4380         break;
   4381       case 1 + 64:
   4382         _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(
   4383             dest_scan, src_scan, width, m_BlendType, src_Bpp, dst_extra_alpha,
   4384             m_pCacheScanline, m_pIccTransform);
   4385         break;
   4386       case 1 + 8:
   4387         _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan, width,
   4388                                           m_BlendType, src_Bpp, clip_scan,
   4389                                           dst_extra_alpha);
   4390         break;
   4391       case 1 + 8 + 64:
   4392         _CompositeRow_Rgb2Argb_Blend_Clip_Transform(
   4393             dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan,
   4394             dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
   4395         break;
   4396       case 1 + 4:
   4397         _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan, width,
   4398                                               src_Bpp, dst_extra_alpha);
   4399         break;
   4400       case 1 + 4 + 64:
   4401         _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(
   4402             dest_scan, src_scan, width, src_Bpp, dst_extra_alpha,
   4403             m_pCacheScanline, m_pIccTransform);
   4404         break;
   4405       case 1 + 4 + 8:
   4406         _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan, width, src_Bpp,
   4407                                             clip_scan, dst_extra_alpha);
   4408         break;
   4409       case 1 + 4 + 8 + 64:
   4410         _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(
   4411             dest_scan, src_scan, width, src_Bpp, clip_scan, dst_extra_alpha,
   4412             m_pCacheScanline, m_pIccTransform);
   4413         break;
   4414       case 2:
   4415       case 2 + 8:
   4416         _CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan, width, m_BlendType,
   4417                                      dest_Bpp, clip_scan, src_extra_alpha);
   4418         break;
   4419       case 2 + 64:
   4420       case 2 + 8 + 64:
   4421         _CompositeRow_Argb2Rgb_Blend_Transform(
   4422             dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan,
   4423             src_extra_alpha, m_pCacheScanline, m_pIccTransform);
   4424         break;
   4425       case 2 + 4:
   4426       case 2 + 4 + 8:
   4427         _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan, width, dest_Bpp,
   4428                                        clip_scan, src_extra_alpha);
   4429         break;
   4430       case 2 + 4 + 64:
   4431       case 2 + 4 + 8 + 64:
   4432         _CompositeRow_Argb2Rgb_NoBlend_Transform(
   4433             dest_scan, src_scan, width, dest_Bpp, clip_scan, src_extra_alpha,
   4434             m_pCacheScanline, m_pIccTransform);
   4435         break;
   4436       case 1 + 2:
   4437         _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan, width,
   4438                                            m_BlendType, dest_Bpp, src_Bpp);
   4439         break;
   4440       case 1 + 2 + 64:
   4441         _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(
   4442             dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp,
   4443             m_pCacheScanline, m_pIccTransform);
   4444         break;
   4445       case 1 + 2 + 8:
   4446         _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan, width,
   4447                                          m_BlendType, dest_Bpp, src_Bpp,
   4448                                          clip_scan);
   4449         break;
   4450       case 1 + 2 + 8 + 64:
   4451         _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(
   4452             dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp,
   4453             clip_scan, m_pCacheScanline, m_pIccTransform);
   4454         break;
   4455       case 1 + 2 + 4:
   4456         _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan, width,
   4457                                              dest_Bpp, src_Bpp);
   4458         break;
   4459       case 1 + 2 + 4 + 64:
   4460         _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(
   4461             dest_scan, src_scan, width, dest_Bpp, src_Bpp, m_pCacheScanline,
   4462             m_pIccTransform);
   4463         break;
   4464       case 1 + 2 + 4 + 8:
   4465         _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan, width, dest_Bpp,
   4466                                            src_Bpp, clip_scan);
   4467         break;
   4468       case 1 + 2 + 4 + 8 + 64:
   4469         _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(
   4470             dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan,
   4471             m_pCacheScanline, m_pIccTransform);
   4472         break;
   4473     }
   4474   }
   4475 }
   4476 void CFX_ScanlineCompositor::CompositePalBitmapLine(
   4477     uint8_t* dest_scan,
   4478     const uint8_t* src_scan,
   4479     int src_left,
   4480     int width,
   4481     const uint8_t* clip_scan,
   4482     const uint8_t* src_extra_alpha,
   4483     uint8_t* dst_extra_alpha) {
   4484   if (m_bRgbByteOrder) {
   4485     if (m_SrcFormat == FXDIB_1bppRgb) {
   4486       if (m_DestFormat == FXDIB_8bppRgb) {
   4487         return;
   4488       }
   4489       if (m_DestFormat == FXDIB_Argb) {
   4490         _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(
   4491             dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan);
   4492       } else {
   4493         _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(
   4494             dest_scan, src_scan, src_left, m_pSrcPalette, width,
   4495             (m_DestFormat & 0xff) >> 3, clip_scan);
   4496       }
   4497     } else {
   4498       if (m_DestFormat == FXDIB_8bppRgb) {
   4499         return;
   4500       }
   4501       if (m_DestFormat == FXDIB_Argb) {
   4502         _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(
   4503             dest_scan, src_scan, width, m_pSrcPalette, clip_scan);
   4504       } else {
   4505         _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(
   4506             dest_scan, src_scan, m_pSrcPalette, width,
   4507             (m_DestFormat & 0xff) >> 3, clip_scan);
   4508       }
   4509     }
   4510     return;
   4511   }
   4512   if (m_DestFormat == FXDIB_8bppMask) {
   4513     _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
   4514     return;
   4515   }
   4516   if ((m_DestFormat & 0xff) == 8) {
   4517     if (m_Transparency & 8) {
   4518       if (m_DestFormat & 0x0200) {
   4519         _CompositeRow_1bppPal2Graya(dest_scan, src_scan, src_left,
   4520                                     (const uint8_t*)m_pSrcPalette, width,
   4521                                     m_BlendType, clip_scan, dst_extra_alpha);
   4522       } else {
   4523         _CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left,
   4524                                    (const uint8_t*)m_pSrcPalette, width,
   4525                                    m_BlendType, clip_scan);
   4526       }
   4527     } else {
   4528       if (m_DestFormat & 0x0200)
   4529         _CompositeRow_8bppPal2Graya(
   4530             dest_scan, src_scan, (const uint8_t*)m_pSrcPalette, width,
   4531             m_BlendType, clip_scan, dst_extra_alpha, src_extra_alpha);
   4532       else
   4533         _CompositeRow_8bppPal2Gray(dest_scan, src_scan,
   4534                                    (const uint8_t*)m_pSrcPalette, width,
   4535                                    m_BlendType, clip_scan, src_extra_alpha);
   4536     }
   4537   } else {
   4538     switch (m_Transparency) {
   4539       case 1 + 2:
   4540         _CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan, width,
   4541                                            m_pSrcPalette, clip_scan,
   4542                                            src_extra_alpha);
   4543         break;
   4544       case 1 + 2 + 8:
   4545         _CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width,
   4546                                            m_pSrcPalette, clip_scan);
   4547         break;
   4548       case 0:
   4549         _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette,
   4550                                           width, (m_DestFormat & 0xff) >> 3,
   4551                                           clip_scan, src_extra_alpha);
   4552         break;
   4553       case 0 + 8:
   4554         _CompositeRow_1bppRgb2Rgb_NoBlend(
   4555             dest_scan, src_scan, src_left, m_pSrcPalette, width,
   4556             (m_DestFormat & 0xff) >> 3, clip_scan);
   4557         break;
   4558       case 0 + 2:
   4559         _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette,
   4560                                           width, (m_DestFormat & 0xff) >> 3,
   4561                                           clip_scan, src_extra_alpha);
   4562         break;
   4563       case 0 + 2 + 8:
   4564         _CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan, src_left, width,
   4565                                            m_pSrcPalette, clip_scan,
   4566                                            dst_extra_alpha);
   4567         break;
   4568         break;
   4569     }
   4570   }
   4571 }
   4572 void CFX_ScanlineCompositor::CompositeByteMaskLine(uint8_t* dest_scan,
   4573                                                    const uint8_t* src_scan,
   4574                                                    int width,
   4575                                                    const uint8_t* clip_scan,
   4576                                                    uint8_t* dst_extra_alpha) {
   4577   if (m_DestFormat == FXDIB_8bppMask) {
   4578     _CompositeRow_ByteMask2Mask(dest_scan, src_scan, m_MaskAlpha, width,
   4579                                 clip_scan);
   4580   } else if ((m_DestFormat & 0xff) == 8) {
   4581     if (m_DestFormat & 0x0200) {
   4582       _CompositeRow_ByteMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
   4583                                    width, clip_scan, dst_extra_alpha);
   4584     } else {
   4585       _CompositeRow_ByteMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
   4586                                   width, clip_scan);
   4587     }
   4588   } else if (m_bRgbByteOrder) {
   4589     if (m_DestFormat == FXDIB_Argb)
   4590       _CompositeRow_ByteMask2Argb_RgbByteOrder(
   4591           dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
   4592           width, m_BlendType, clip_scan);
   4593     else
   4594       _CompositeRow_ByteMask2Rgb_RgbByteOrder(
   4595           dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
   4596           width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
   4597     return;
   4598   } else if (m_DestFormat == FXDIB_Argb)
   4599     _CompositeRow_ByteMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
   4600                                 m_MaskGreen, m_MaskBlue, width, m_BlendType,
   4601                                 clip_scan);
   4602   else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
   4603     _CompositeRow_ByteMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
   4604                                m_MaskGreen, m_MaskBlue, width, m_BlendType,
   4605                                (m_DestFormat & 0xff) >> 3, clip_scan);
   4606   else if (m_DestFormat == FXDIB_Rgba)
   4607     _CompositeRow_ByteMask2Rgba(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
   4608                                 m_MaskGreen, m_MaskBlue, width, m_BlendType,
   4609                                 clip_scan, dst_extra_alpha);
   4610 }
   4611 void CFX_ScanlineCompositor::CompositeBitMaskLine(uint8_t* dest_scan,
   4612                                                   const uint8_t* src_scan,
   4613                                                   int src_left,
   4614                                                   int width,
   4615                                                   const uint8_t* clip_scan,
   4616                                                   uint8_t* dst_extra_alpha) {
   4617   if (m_DestFormat == FXDIB_8bppMask) {
   4618     _CompositeRow_BitMask2Mask(dest_scan, src_scan, m_MaskAlpha, src_left,
   4619                                width, clip_scan);
   4620   } else if ((m_DestFormat & 0xff) == 8) {
   4621     if (m_DestFormat & 0x0200)
   4622       _CompositeRow_BitMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
   4623                                   src_left, width, clip_scan, dst_extra_alpha);
   4624     else {
   4625       _CompositeRow_BitMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
   4626                                  src_left, width, clip_scan);
   4627     }
   4628   } else if (m_bRgbByteOrder) {
   4629     if (m_DestFormat == FXDIB_Argb)
   4630       _CompositeRow_BitMask2Argb_RgbByteOrder(
   4631           dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
   4632           src_left, width, m_BlendType, clip_scan);
   4633     else
   4634       _CompositeRow_BitMask2Rgb_RgbByteOrder(
   4635           dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
   4636           src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
   4637     return;
   4638   } else if (m_DestFormat == FXDIB_Argb)
   4639     _CompositeRow_BitMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
   4640                                m_MaskGreen, m_MaskBlue, src_left, width,
   4641                                m_BlendType, clip_scan);
   4642   else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
   4643     _CompositeRow_BitMask2Rgb(
   4644         dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
   4645         src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
   4646 }
   4647 FX_BOOL CFX_DIBitmap::CompositeBitmap(int dest_left,
   4648                                       int dest_top,
   4649                                       int width,
   4650                                       int height,
   4651                                       const CFX_DIBSource* pSrcBitmap,
   4652                                       int src_left,
   4653                                       int src_top,
   4654                                       int blend_type,
   4655                                       const CFX_ClipRgn* pClipRgn,
   4656                                       FX_BOOL bRgbByteOrder,
   4657                                       void* pIccTransform) {
   4658   if (!m_pBuffer) {
   4659     return FALSE;
   4660   }
   4661   ASSERT(!pSrcBitmap->IsAlphaMask());
   4662   ASSERT(m_bpp >= 8);
   4663   if (pSrcBitmap->IsAlphaMask() || m_bpp < 8) {
   4664     return FALSE;
   4665   }
   4666   GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(),
   4667                  pSrcBitmap->GetHeight(), src_left, src_top, pClipRgn);
   4668   if (width == 0 || height == 0) {
   4669     return TRUE;
   4670   }
   4671   const CFX_DIBitmap* pClipMask = NULL;
   4672   FX_RECT clip_box;
   4673   if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
   4674     ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
   4675     pClipMask = pClipRgn->GetMask();
   4676     clip_box = pClipRgn->GetBox();
   4677   }
   4678   CFX_ScanlineCompositor compositor;
   4679   if (!compositor.Init(GetFormat(), pSrcBitmap->GetFormat(), width,
   4680                        pSrcBitmap->GetPalette(), 0, blend_type,
   4681                        pClipMask != NULL, bRgbByteOrder, 0, pIccTransform)) {
   4682     return FALSE;
   4683   }
   4684   int dest_Bpp = m_bpp / 8;
   4685   int src_Bpp = pSrcBitmap->GetBPP() / 8;
   4686   FX_BOOL bRgb = src_Bpp > 1 && !pSrcBitmap->IsCmykImage();
   4687   CFX_DIBitmap* pSrcAlphaMask = pSrcBitmap->m_pAlphaMask;
   4688   for (int row = 0; row < height; row++) {
   4689     uint8_t* dest_scan =
   4690         m_pBuffer + (dest_top + row) * m_Pitch + dest_left * dest_Bpp;
   4691     const uint8_t* src_scan =
   4692         pSrcBitmap->GetScanline(src_top + row) + src_left * src_Bpp;
   4693     const uint8_t* src_scan_extra_alpha =
   4694         pSrcAlphaMask ? pSrcAlphaMask->GetScanline(src_top + row) + src_left
   4695                       : NULL;
   4696     uint8_t* dst_scan_extra_alpha =
   4697         m_pAlphaMask
   4698             ? (uint8_t*)m_pAlphaMask->GetScanline(dest_top + row) + dest_left
   4699             : NULL;
   4700     const uint8_t* clip_scan = NULL;
   4701     if (pClipMask) {
   4702       clip_scan = pClipMask->m_pBuffer +
   4703                   (dest_top + row - clip_box.top) * pClipMask->m_Pitch +
   4704                   (dest_left - clip_box.left);
   4705     }
   4706     if (bRgb) {
   4707       compositor.CompositeRgbBitmapLine(dest_scan, src_scan, width, clip_scan,
   4708                                         src_scan_extra_alpha,
   4709                                         dst_scan_extra_alpha);
   4710     } else {
   4711       compositor.CompositePalBitmapLine(dest_scan, src_scan, src_left, width,
   4712                                         clip_scan, src_scan_extra_alpha,
   4713                                         dst_scan_extra_alpha);
   4714     }
   4715   }
   4716   return TRUE;
   4717 }
   4718 FX_BOOL CFX_DIBitmap::CompositeMask(int dest_left,
   4719                                     int dest_top,
   4720                                     int width,
   4721                                     int height,
   4722                                     const CFX_DIBSource* pMask,
   4723                                     FX_DWORD color,
   4724                                     int src_left,
   4725                                     int src_top,
   4726                                     int blend_type,
   4727                                     const CFX_ClipRgn* pClipRgn,
   4728                                     FX_BOOL bRgbByteOrder,
   4729                                     int alpha_flag,
   4730                                     void* pIccTransform) {
   4731   if (!m_pBuffer) {
   4732     return FALSE;
   4733   }
   4734   ASSERT(pMask->IsAlphaMask());
   4735   ASSERT(m_bpp >= 8);
   4736   if (!pMask->IsAlphaMask() || m_bpp < 8) {
   4737     return FALSE;
   4738   }
   4739   GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(),
   4740                  pMask->GetHeight(), src_left, src_top, pClipRgn);
   4741   if (width == 0 || height == 0) {
   4742     return TRUE;
   4743   }
   4744   int src_alpha =
   4745       (uint8_t)(alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
   4746   if (src_alpha == 0) {
   4747     return TRUE;
   4748   }
   4749   const CFX_DIBitmap* pClipMask = NULL;
   4750   FX_RECT clip_box;
   4751   if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
   4752     ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
   4753     pClipMask = pClipRgn->GetMask();
   4754     clip_box = pClipRgn->GetBox();
   4755   }
   4756   int src_bpp = pMask->GetBPP();
   4757   int Bpp = GetBPP() / 8;
   4758   CFX_ScanlineCompositor compositor;
   4759   if (!compositor.Init(GetFormat(), pMask->GetFormat(), width, NULL, color,
   4760                        blend_type, pClipMask != NULL, bRgbByteOrder, alpha_flag,
   4761                        pIccTransform)) {
   4762     return FALSE;
   4763   }
   4764   for (int row = 0; row < height; row++) {
   4765     uint8_t* dest_scan =
   4766         m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp;
   4767     const uint8_t* src_scan = pMask->GetScanline(src_top + row);
   4768     uint8_t* dst_scan_extra_alpha =
   4769         m_pAlphaMask
   4770             ? (uint8_t*)m_pAlphaMask->GetScanline(dest_top + row) + dest_left
   4771             : NULL;
   4772     const uint8_t* clip_scan = NULL;
   4773     if (pClipMask) {
   4774       clip_scan = pClipMask->m_pBuffer +
   4775                   (dest_top + row - clip_box.top) * pClipMask->m_Pitch +
   4776                   (dest_left - clip_box.left);
   4777     }
   4778     if (src_bpp == 1) {
   4779       compositor.CompositeBitMaskLine(dest_scan, src_scan, src_left, width,
   4780                                       clip_scan, dst_scan_extra_alpha);
   4781     } else {
   4782       compositor.CompositeByteMaskLine(dest_scan, src_scan + src_left, width,
   4783                                        clip_scan, dst_scan_extra_alpha);
   4784     }
   4785   }
   4786   return TRUE;
   4787 }
   4788 FX_BOOL CFX_DIBitmap::CompositeRect(int left,
   4789                                     int top,
   4790                                     int width,
   4791                                     int height,
   4792                                     FX_DWORD color,
   4793                                     int alpha_flag,
   4794                                     void* pIccTransform) {
   4795   if (!m_pBuffer) {
   4796     return FALSE;
   4797   }
   4798   int src_alpha = (alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
   4799   if (src_alpha == 0) {
   4800     return TRUE;
   4801   }
   4802   FX_RECT rect(left, top, left + width, top + height);
   4803   rect.Intersect(0, 0, m_Width, m_Height);
   4804   if (rect.IsEmpty()) {
   4805     return TRUE;
   4806   }
   4807   width = rect.Width();
   4808   FX_DWORD dst_color;
   4809   if (alpha_flag >> 8) {
   4810     dst_color = FXCMYK_TODIB(color);
   4811   } else {
   4812     dst_color = FXARGB_TODIB(color);
   4813   }
   4814   uint8_t* color_p = (uint8_t*)&dst_color;
   4815   if (m_bpp == 8) {
   4816     uint8_t gray = 255;
   4817     if (!IsAlphaMask()) {
   4818       if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() &&
   4819           CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
   4820         ICodec_IccModule* pIccModule =
   4821             CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   4822         pIccModule->TranslateScanline(pIccTransform, &gray, color_p, 1);
   4823       } else {
   4824         if (alpha_flag >> 8) {
   4825           uint8_t r, g, b;
   4826           AdobeCMYK_to_sRGB1(color_p[0], color_p[1], color_p[2], color_p[3], r,
   4827                              g, b);
   4828           gray = FXRGB2GRAY(r, g, b);
   4829         } else {
   4830           gray = (uint8_t)FXRGB2GRAY((int)color_p[2], color_p[1], color_p[0]);
   4831         }
   4832       }
   4833       if (IsCmykImage()) {
   4834         gray = ~gray;
   4835       }
   4836     }
   4837     for (int row = rect.top; row < rect.bottom; row++) {
   4838       uint8_t* dest_scan = m_pBuffer + row * m_Pitch + rect.left;
   4839       if (src_alpha == 255) {
   4840         FXSYS_memset(dest_scan, gray, width);
   4841       } else
   4842         for (int col = 0; col < width; col++) {
   4843           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
   4844           dest_scan++;
   4845         }
   4846     }
   4847     return TRUE;
   4848   }
   4849   if (m_bpp == 1) {
   4850     ASSERT(!IsCmykImage() && (uint8_t)(alpha_flag >> 8) == 0);
   4851     int left_shift = rect.left % 8;
   4852     int right_shift = rect.right % 8;
   4853     int width = rect.right / 8 - rect.left / 8;
   4854     int index = 0;
   4855     if (m_pPalette) {
   4856       for (int i = 0; i < 2; i++) {
   4857         if (m_pPalette[i] == color) {
   4858           index = i;
   4859         }
   4860       }
   4861     } else {
   4862       index = ((uint8_t)color == 0xff) ? 1 : 0;
   4863     }
   4864     for (int row = rect.top; row < rect.bottom; row++) {
   4865       uint8_t* dest_scan_top = (uint8_t*)GetScanline(row) + rect.left / 8;
   4866       uint8_t* dest_scan_top_r = (uint8_t*)GetScanline(row) + rect.right / 8;
   4867       uint8_t left_flag = *dest_scan_top & (255 << (8 - left_shift));
   4868       uint8_t right_flag = *dest_scan_top_r & (255 >> right_shift);
   4869       if (width) {
   4870         FXSYS_memset(dest_scan_top + 1, index ? 255 : 0, width - 1);
   4871         if (!index) {
   4872           *dest_scan_top &= left_flag;
   4873           *dest_scan_top_r &= right_flag;
   4874         } else {
   4875           *dest_scan_top |= ~left_flag;
   4876           *dest_scan_top_r |= ~right_flag;
   4877         }
   4878       } else {
   4879         if (!index) {
   4880           *dest_scan_top &= left_flag | right_flag;
   4881         } else {
   4882           *dest_scan_top |= ~(left_flag | right_flag);
   4883         }
   4884       }
   4885     }
   4886     return TRUE;
   4887   }
   4888   ASSERT(m_bpp >= 24);
   4889   if (m_bpp < 24) {
   4890     return FALSE;
   4891   }
   4892   if (pIccTransform && CFX_GEModule::Get()->GetCodecModule()) {
   4893     ICodec_IccModule* pIccModule =
   4894         CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   4895     pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1);
   4896   } else {
   4897     if (alpha_flag >> 8 && !IsCmykImage())
   4898       AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color),
   4899                          FXSYS_GetYValue(color), FXSYS_GetKValue(color),
   4900                          color_p[2], color_p[1], color_p[0]);
   4901     else if (!(alpha_flag >> 8) && IsCmykImage()) {
   4902       return FALSE;
   4903     }
   4904   }
   4905   if (!IsCmykImage()) {
   4906     color_p[3] = (uint8_t)src_alpha;
   4907   }
   4908   int Bpp = m_bpp / 8;
   4909   FX_BOOL bAlpha = HasAlpha();
   4910   FX_BOOL bArgb = GetFormat() == FXDIB_Argb;
   4911   if (src_alpha == 255) {
   4912     for (int row = rect.top; row < rect.bottom; row++) {
   4913       uint8_t* dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
   4914       uint8_t* dest_scan_alpha =
   4915           m_pAlphaMask ? (uint8_t*)m_pAlphaMask->GetScanline(row) + rect.left
   4916                        : NULL;
   4917       if (dest_scan_alpha) {
   4918         FXSYS_memset(dest_scan_alpha, 0xff, width);
   4919       }
   4920       if (Bpp == 4) {
   4921         FX_DWORD* scan = (FX_DWORD*)dest_scan;
   4922         for (int col = 0; col < width; col++) {
   4923           *scan++ = dst_color;
   4924         }
   4925       } else {
   4926         for (int col = 0; col < width; col++) {
   4927           *dest_scan++ = color_p[0];
   4928           *dest_scan++ = color_p[1];
   4929           *dest_scan++ = color_p[2];
   4930         }
   4931       }
   4932     }
   4933     return TRUE;
   4934   }
   4935   for (int row = rect.top; row < rect.bottom; row++) {
   4936     uint8_t* dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
   4937     if (bAlpha) {
   4938       if (bArgb) {
   4939         for (int col = 0; col < width; col++) {
   4940           uint8_t back_alpha = dest_scan[3];
   4941           if (back_alpha == 0) {
   4942             FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, color_p[2],
   4943                                                  color_p[1], color_p[0]));
   4944             dest_scan += 4;
   4945             continue;
   4946           }
   4947           uint8_t dest_alpha =
   4948               back_alpha + src_alpha - back_alpha * src_alpha / 255;
   4949           int alpha_ratio = src_alpha * 255 / dest_alpha;
   4950           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[0], alpha_ratio);
   4951           dest_scan++;
   4952           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[1], alpha_ratio);
   4953           dest_scan++;
   4954           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[2], alpha_ratio);
   4955           dest_scan++;
   4956           *dest_scan++ = dest_alpha;
   4957         }
   4958       } else {
   4959         uint8_t* dest_scan_alpha =
   4960             (uint8_t*)m_pAlphaMask->GetScanline(row) + rect.left;
   4961         for (int col = 0; col < width; col++) {
   4962           uint8_t back_alpha = *dest_scan_alpha;
   4963           if (back_alpha == 0) {
   4964             *dest_scan_alpha++ = src_alpha;
   4965             FXSYS_memcpy(dest_scan, color_p, Bpp);
   4966             dest_scan += Bpp;
   4967             continue;
   4968           }
   4969           uint8_t dest_alpha =
   4970               back_alpha + src_alpha - back_alpha * src_alpha / 255;
   4971           *dest_scan_alpha++ = dest_alpha;
   4972           int alpha_ratio = src_alpha * 255 / dest_alpha;
   4973           for (int comps = 0; comps < Bpp; comps++) {
   4974             *dest_scan =
   4975                 FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], alpha_ratio);
   4976             dest_scan++;
   4977           }
   4978         }
   4979       }
   4980     } else {
   4981       for (int col = 0; col < width; col++) {
   4982         for (int comps = 0; comps < Bpp; comps++) {
   4983           if (comps == 3) {
   4984             *dest_scan++ = 255;
   4985             continue;
   4986           }
   4987           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], src_alpha);
   4988           dest_scan++;
   4989         }
   4990       }
   4991     }
   4992   }
   4993   return TRUE;
   4994 }
   4995 CFX_BitmapComposer::CFX_BitmapComposer() {
   4996   m_pScanlineV = NULL;
   4997   m_pScanlineAlphaV = NULL;
   4998   m_pClipScanV = NULL;
   4999   m_pAddClipScan = NULL;
   5000   m_bRgbByteOrder = FALSE;
   5001   m_BlendType = FXDIB_BLEND_NORMAL;
   5002 }
   5003 CFX_BitmapComposer::~CFX_BitmapComposer() {
   5004   FX_Free(m_pScanlineV);
   5005   FX_Free(m_pScanlineAlphaV);
   5006   FX_Free(m_pClipScanV);
   5007   FX_Free(m_pAddClipScan);
   5008 }
   5009 void CFX_BitmapComposer::Compose(CFX_DIBitmap* pDest,
   5010                                  const CFX_ClipRgn* pClipRgn,
   5011                                  int bitmap_alpha,
   5012                                  FX_DWORD mask_color,
   5013                                  FX_RECT& dest_rect,
   5014                                  FX_BOOL bVertical,
   5015                                  FX_BOOL bFlipX,
   5016                                  FX_BOOL bFlipY,
   5017                                  FX_BOOL bRgbByteOrder,
   5018                                  int alpha_flag,
   5019                                  void* pIccTransform,
   5020                                  int blend_type) {
   5021   m_pBitmap = pDest;
   5022   m_pClipRgn = pClipRgn;
   5023   m_DestLeft = dest_rect.left;
   5024   m_DestTop = dest_rect.top;
   5025   m_DestWidth = dest_rect.Width();
   5026   m_DestHeight = dest_rect.Height();
   5027   m_BitmapAlpha = bitmap_alpha;
   5028   m_MaskColor = mask_color;
   5029   m_pClipMask = NULL;
   5030   if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
   5031     m_pClipMask = pClipRgn->GetMask();
   5032   }
   5033   m_bVertical = bVertical;
   5034   m_bFlipX = bFlipX;
   5035   m_bFlipY = bFlipY;
   5036   m_AlphaFlag = alpha_flag;
   5037   m_pIccTransform = pIccTransform;
   5038   m_bRgbByteOrder = bRgbByteOrder;
   5039   m_BlendType = blend_type;
   5040 }
   5041 FX_BOOL CFX_BitmapComposer::SetInfo(int width,
   5042                                     int height,
   5043                                     FXDIB_Format src_format,
   5044                                     FX_DWORD* pSrcPalette) {
   5045   m_SrcFormat = src_format;
   5046   if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, width, pSrcPalette,
   5047                          m_MaskColor, FXDIB_BLEND_NORMAL,
   5048                          m_pClipMask != NULL || (m_BitmapAlpha < 255),
   5049                          m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform)) {
   5050     return FALSE;
   5051   }
   5052   if (m_bVertical) {
   5053     m_pScanlineV = FX_Alloc(uint8_t, m_pBitmap->GetBPP() / 8 * width + 4);
   5054     m_pClipScanV = FX_Alloc(uint8_t, m_pBitmap->GetHeight());
   5055     if (m_pBitmap->m_pAlphaMask) {
   5056       m_pScanlineAlphaV = FX_Alloc(uint8_t, width + 4);
   5057     }
   5058   }
   5059   if (m_BitmapAlpha < 255) {
   5060     m_pAddClipScan = FX_Alloc(
   5061         uint8_t, m_bVertical ? m_pBitmap->GetHeight() : m_pBitmap->GetWidth());
   5062   }
   5063   return TRUE;
   5064 }
   5065 void CFX_BitmapComposer::DoCompose(uint8_t* dest_scan,
   5066                                    const uint8_t* src_scan,
   5067                                    int dest_width,
   5068                                    const uint8_t* clip_scan,
   5069                                    const uint8_t* src_extra_alpha,
   5070                                    uint8_t* dst_extra_alpha) {
   5071   if (m_BitmapAlpha < 255) {
   5072     if (clip_scan) {
   5073       for (int i = 0; i < dest_width; i++) {
   5074         m_pAddClipScan[i] = clip_scan[i] * m_BitmapAlpha / 255;
   5075       }
   5076     } else {
   5077       FXSYS_memset(m_pAddClipScan, m_BitmapAlpha, dest_width);
   5078     }
   5079     clip_scan = m_pAddClipScan;
   5080   }
   5081   if (m_SrcFormat == FXDIB_8bppMask) {
   5082     m_Compositor.CompositeByteMaskLine(dest_scan, src_scan, dest_width,
   5083                                        clip_scan, dst_extra_alpha);
   5084   } else if ((m_SrcFormat & 0xff) == 8) {
   5085     m_Compositor.CompositePalBitmapLine(dest_scan, src_scan, 0, dest_width,
   5086                                         clip_scan, src_extra_alpha,
   5087                                         dst_extra_alpha);
   5088   } else {
   5089     m_Compositor.CompositeRgbBitmapLine(dest_scan, src_scan, dest_width,
   5090                                         clip_scan, src_extra_alpha,
   5091                                         dst_extra_alpha);
   5092   }
   5093 }
   5094 void CFX_BitmapComposer::ComposeScanline(int line,
   5095                                          const uint8_t* scanline,
   5096                                          const uint8_t* scan_extra_alpha) {
   5097   if (m_bVertical) {
   5098     ComposeScanlineV(line, scanline, scan_extra_alpha);
   5099     return;
   5100   }
   5101   const uint8_t* clip_scan = NULL;
   5102   if (m_pClipMask)
   5103     clip_scan = m_pClipMask->GetBuffer() +
   5104                 (m_DestTop + line - m_pClipRgn->GetBox().top) *
   5105                     m_pClipMask->GetPitch() +
   5106                 (m_DestLeft - m_pClipRgn->GetBox().left);
   5107   uint8_t* dest_scan = (uint8_t*)m_pBitmap->GetScanline(line + m_DestTop) +
   5108                        m_DestLeft * m_pBitmap->GetBPP() / 8;
   5109   uint8_t* dest_alpha_scan =
   5110       m_pBitmap->m_pAlphaMask
   5111           ? (uint8_t*)m_pBitmap->m_pAlphaMask->GetScanline(line + m_DestTop) +
   5112                 m_DestLeft
   5113           : NULL;
   5114   DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha,
   5115             dest_alpha_scan);
   5116 }
   5117 void CFX_BitmapComposer::ComposeScanlineV(int line,
   5118                                           const uint8_t* scanline,
   5119                                           const uint8_t* scan_extra_alpha) {
   5120   int i;
   5121   int Bpp = m_pBitmap->GetBPP() / 8;
   5122   int dest_pitch = m_pBitmap->GetPitch();
   5123   int dest_alpha_pitch =
   5124       m_pBitmap->m_pAlphaMask ? m_pBitmap->m_pAlphaMask->GetPitch() : 0;
   5125   int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line);
   5126   uint8_t* dest_buf =
   5127       m_pBitmap->GetBuffer() + dest_x * Bpp + m_DestTop * dest_pitch;
   5128   uint8_t* dest_alpha_buf = m_pBitmap->m_pAlphaMask
   5129                                 ? m_pBitmap->m_pAlphaMask->GetBuffer() +
   5130                                       dest_x + m_DestTop * dest_alpha_pitch
   5131                                 : NULL;
   5132   if (m_bFlipY) {
   5133     dest_buf += dest_pitch * (m_DestHeight - 1);
   5134     dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1);
   5135   }
   5136   int y_step = dest_pitch;
   5137   int y_alpha_step = dest_alpha_pitch;
   5138   if (m_bFlipY) {
   5139     y_step = -y_step;
   5140     y_alpha_step = -y_alpha_step;
   5141   }
   5142   uint8_t* src_scan = m_pScanlineV;
   5143   uint8_t* dest_scan = dest_buf;
   5144   for (i = 0; i < m_DestHeight; i++) {
   5145     for (int j = 0; j < Bpp; j++) {
   5146       *src_scan++ = dest_scan[j];
   5147     }
   5148     dest_scan += y_step;
   5149   }
   5150   uint8_t* src_alpha_scan = m_pScanlineAlphaV;
   5151   uint8_t* dest_alpha_scan = dest_alpha_buf;
   5152   if (dest_alpha_scan) {
   5153     for (i = 0; i < m_DestHeight; i++) {
   5154       *src_alpha_scan++ = *dest_alpha_scan;
   5155       dest_alpha_scan += y_alpha_step;
   5156     }
   5157   }
   5158   uint8_t* clip_scan = NULL;
   5159   if (m_pClipMask) {
   5160     clip_scan = m_pClipScanV;
   5161     int clip_pitch = m_pClipMask->GetPitch();
   5162     const uint8_t* src_clip =
   5163         m_pClipMask->GetBuffer() +
   5164         (m_DestTop - m_pClipRgn->GetBox().top) * clip_pitch +
   5165         (dest_x - m_pClipRgn->GetBox().left);
   5166     if (m_bFlipY) {
   5167       src_clip += clip_pitch * (m_DestHeight - 1);
   5168       clip_pitch = -clip_pitch;
   5169     }
   5170     for (i = 0; i < m_DestHeight; i++) {
   5171       clip_scan[i] = *src_clip;
   5172       src_clip += clip_pitch;
   5173     }
   5174   }
   5175   DoCompose(m_pScanlineV, scanline, m_DestHeight, clip_scan, scan_extra_alpha,
   5176             m_pScanlineAlphaV);
   5177   src_scan = m_pScanlineV;
   5178   dest_scan = dest_buf;
   5179   for (i = 0; i < m_DestHeight; i++) {
   5180     for (int j = 0; j < Bpp; j++) {
   5181       dest_scan[j] = *src_scan++;
   5182     }
   5183     dest_scan += y_step;
   5184   }
   5185   src_alpha_scan = m_pScanlineAlphaV;
   5186   dest_alpha_scan = dest_alpha_buf;
   5187   if (dest_alpha_scan) {
   5188     for (i = 0; i < m_DestHeight; i++) {
   5189       *dest_alpha_scan = *src_alpha_scan++;
   5190       dest_alpha_scan += y_alpha_step;
   5191     }
   5192   }
   5193 }
   5194