Home | History | Annotate | Download | only in base
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  ftbitmap.c                                                             */
      4 /*                                                                         */
      5 /*    FreeType utility functions for bitmaps (body).                       */
      6 /*                                                                         */
      7 /*  Copyright 2004-2018 by                                                 */
      8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
      9 /*                                                                         */
     10 /*  This file is part of the FreeType project, and may only be used,       */
     11 /*  modified, and distributed under the terms of the FreeType project      */
     12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
     13 /*  this file you indicate that you have read the license and              */
     14 /*  understand and accept it fully.                                        */
     15 /*                                                                         */
     16 /***************************************************************************/
     17 
     18 
     19 #include <ft2build.h>
     20 #include FT_INTERNAL_DEBUG_H
     21 
     22 #include FT_BITMAP_H
     23 #include FT_IMAGE_H
     24 #include FT_INTERNAL_OBJECTS_H
     25 
     26 
     27   static
     28   const FT_Bitmap  null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 };
     29 
     30 
     31   /* documentation is in ftbitmap.h */
     32 
     33   FT_EXPORT_DEF( void )
     34   FT_Bitmap_Init( FT_Bitmap  *abitmap )
     35   {
     36     if ( abitmap )
     37       *abitmap = null_bitmap;
     38   }
     39 
     40 
     41   /* deprecated function name; retained for ABI compatibility */
     42 
     43   FT_EXPORT_DEF( void )
     44   FT_Bitmap_New( FT_Bitmap  *abitmap )
     45   {
     46     if ( abitmap )
     47       *abitmap = null_bitmap;
     48   }
     49 
     50 
     51   /* documentation is in ftbitmap.h */
     52 
     53   FT_EXPORT_DEF( FT_Error )
     54   FT_Bitmap_Copy( FT_Library        library,
     55                   const FT_Bitmap  *source,
     56                   FT_Bitmap        *target)
     57   {
     58     FT_Memory  memory;
     59     FT_Error   error  = FT_Err_Ok;
     60 
     61     FT_Int    pitch;
     62     FT_ULong  size;
     63 
     64     FT_Int  source_pitch_sign, target_pitch_sign;
     65 
     66 
     67     if ( !library )
     68       return FT_THROW( Invalid_Library_Handle );
     69 
     70     if ( !source || !target )
     71       return FT_THROW( Invalid_Argument );
     72 
     73     if ( source == target )
     74       return FT_Err_Ok;
     75 
     76     source_pitch_sign = source->pitch < 0 ? -1 : 1;
     77     target_pitch_sign = target->pitch < 0 ? -1 : 1;
     78 
     79     if ( !source->buffer )
     80     {
     81       *target = *source;
     82       if ( source_pitch_sign != target_pitch_sign )
     83         target->pitch = -target->pitch;
     84 
     85       return FT_Err_Ok;
     86     }
     87 
     88     memory = library->memory;
     89     pitch  = source->pitch;
     90 
     91     if ( pitch < 0 )
     92       pitch = -pitch;
     93     size = (FT_ULong)pitch * source->rows;
     94 
     95     if ( target->buffer )
     96     {
     97       FT_Int    target_pitch = target->pitch;
     98       FT_ULong  target_size;
     99 
    100 
    101       if ( target_pitch < 0 )
    102         target_pitch = -target_pitch;
    103       target_size = (FT_ULong)target_pitch * target->rows;
    104 
    105       if ( target_size != size )
    106         (void)FT_QREALLOC( target->buffer, target_size, size );
    107     }
    108     else
    109       (void)FT_QALLOC( target->buffer, size );
    110 
    111     if ( !error )
    112     {
    113       unsigned char *p;
    114 
    115 
    116       p = target->buffer;
    117       *target = *source;
    118       target->buffer = p;
    119 
    120       if ( source_pitch_sign == target_pitch_sign )
    121         FT_MEM_COPY( target->buffer, source->buffer, size );
    122       else
    123       {
    124         /* take care of bitmap flow */
    125         FT_UInt   i;
    126         FT_Byte*  s = source->buffer;
    127         FT_Byte*  t = target->buffer;
    128 
    129 
    130         t += (FT_ULong)pitch * ( target->rows - 1 );
    131 
    132         for ( i = target->rows; i > 0; i-- )
    133         {
    134           FT_ARRAY_COPY( t, s, pitch );
    135 
    136           s += pitch;
    137           t -= pitch;
    138         }
    139       }
    140     }
    141 
    142     return error;
    143   }
    144 
    145 
    146   /* Enlarge `bitmap' horizontally and vertically by `xpixels' */
    147   /* and `ypixels', respectively.                              */
    148 
    149   static FT_Error
    150   ft_bitmap_assure_buffer( FT_Memory   memory,
    151                            FT_Bitmap*  bitmap,
    152                            FT_UInt     xpixels,
    153                            FT_UInt     ypixels )
    154   {
    155     FT_Error        error;
    156     unsigned int    pitch;
    157     unsigned int    new_pitch;
    158     FT_UInt         bpp;
    159     FT_UInt         width, height;
    160     unsigned char*  buffer = NULL;
    161 
    162 
    163     width  = bitmap->width;
    164     height = bitmap->rows;
    165     pitch  = (unsigned int)FT_ABS( bitmap->pitch );
    166 
    167     switch ( bitmap->pixel_mode )
    168     {
    169     case FT_PIXEL_MODE_MONO:
    170       bpp       = 1;
    171       new_pitch = ( width + xpixels + 7 ) >> 3;
    172       break;
    173     case FT_PIXEL_MODE_GRAY2:
    174       bpp       = 2;
    175       new_pitch = ( width + xpixels + 3 ) >> 2;
    176       break;
    177     case FT_PIXEL_MODE_GRAY4:
    178       bpp       = 4;
    179       new_pitch = ( width + xpixels + 1 ) >> 1;
    180       break;
    181     case FT_PIXEL_MODE_GRAY:
    182     case FT_PIXEL_MODE_LCD:
    183     case FT_PIXEL_MODE_LCD_V:
    184       bpp       = 8;
    185       new_pitch = width + xpixels;
    186       break;
    187     default:
    188       return FT_THROW( Invalid_Glyph_Format );
    189     }
    190 
    191     /* if no need to allocate memory */
    192     if ( ypixels == 0 && new_pitch <= pitch )
    193     {
    194       /* zero the padding */
    195       FT_UInt  bit_width = pitch * 8;
    196       FT_UInt  bit_last  = ( width + xpixels ) * bpp;
    197 
    198 
    199       if ( bit_last < bit_width )
    200       {
    201         FT_Byte*  line  = bitmap->buffer + ( bit_last >> 3 );
    202         FT_Byte*  end   = bitmap->buffer + pitch;
    203         FT_UInt   shift = bit_last & 7;
    204         FT_UInt   mask  = 0xFF00U >> shift;
    205         FT_UInt   count = height;
    206 
    207 
    208         for ( ; count > 0; count--, line += pitch, end += pitch )
    209         {
    210           FT_Byte*  write = line;
    211 
    212 
    213           if ( shift > 0 )
    214           {
    215             write[0] = (FT_Byte)( write[0] & mask );
    216             write++;
    217           }
    218           if ( write < end )
    219             FT_MEM_ZERO( write, end - write );
    220         }
    221       }
    222 
    223       return FT_Err_Ok;
    224     }
    225 
    226     /* otherwise allocate new buffer */
    227     if ( FT_QALLOC_MULT( buffer, bitmap->rows + ypixels, new_pitch ) )
    228       return error;
    229 
    230     /* new rows get added at the top of the bitmap, */
    231     /* thus take care of the flow direction         */
    232     if ( bitmap->pitch > 0 )
    233     {
    234       FT_UInt  len = ( width * bpp + 7 ) >> 3;
    235 
    236       unsigned char*  in  = bitmap->buffer;
    237       unsigned char*  out = buffer;
    238 
    239       unsigned char*  limit = bitmap->buffer + pitch * bitmap->rows;
    240       unsigned int    delta = new_pitch - pitch;
    241 
    242 
    243       FT_MEM_ZERO( out, new_pitch * ypixels );
    244       out += new_pitch * ypixels;
    245 
    246       while ( in < limit )
    247       {
    248         FT_MEM_COPY( out, in, len );
    249         in  += pitch;
    250         out += pitch;
    251 
    252         FT_MEM_ZERO( out, delta );
    253         out += delta;
    254       }
    255     }
    256     else
    257     {
    258       FT_UInt  len = ( width * bpp + 7 ) >> 3;
    259 
    260       unsigned char*  in  = bitmap->buffer;
    261       unsigned char*  out = buffer;
    262 
    263       unsigned char*  limit = bitmap->buffer + pitch * bitmap->rows;
    264       unsigned int    delta = new_pitch - pitch;
    265 
    266 
    267       while ( in < limit )
    268       {
    269         FT_MEM_COPY( out, in, len );
    270         in  += pitch;
    271         out += pitch;
    272 
    273         FT_MEM_ZERO( out, delta );
    274         out += delta;
    275       }
    276 
    277       FT_MEM_ZERO( out, new_pitch * ypixels );
    278     }
    279 
    280     FT_FREE( bitmap->buffer );
    281     bitmap->buffer = buffer;
    282 
    283     /* set pitch only, width and height are left untouched */
    284     if ( bitmap->pitch < 0 )
    285       bitmap->pitch = -(int)new_pitch;
    286     else
    287       bitmap->pitch = (int)new_pitch;
    288 
    289     return FT_Err_Ok;
    290   }
    291 
    292 
    293   /* documentation is in ftbitmap.h */
    294 
    295   FT_EXPORT_DEF( FT_Error )
    296   FT_Bitmap_Embolden( FT_Library  library,
    297                       FT_Bitmap*  bitmap,
    298                       FT_Pos      xStrength,
    299                       FT_Pos      yStrength )
    300   {
    301     FT_Error        error;
    302     unsigned char*  p;
    303     FT_Int          i, x, pitch;
    304     FT_UInt         y;
    305     FT_Int          xstr, ystr;
    306 
    307 
    308     if ( !library )
    309       return FT_THROW( Invalid_Library_Handle );
    310 
    311     if ( !bitmap || !bitmap->buffer )
    312       return FT_THROW( Invalid_Argument );
    313 
    314     if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||
    315          ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )
    316       return FT_THROW( Invalid_Argument );
    317 
    318     xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
    319     ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;
    320 
    321     if ( xstr == 0 && ystr == 0 )
    322       return FT_Err_Ok;
    323     else if ( xstr < 0 || ystr < 0 )
    324       return FT_THROW( Invalid_Argument );
    325 
    326     switch ( bitmap->pixel_mode )
    327     {
    328     case FT_PIXEL_MODE_GRAY2:
    329     case FT_PIXEL_MODE_GRAY4:
    330       {
    331         FT_Bitmap  tmp;
    332 
    333 
    334         /* convert to 8bpp */
    335         FT_Bitmap_Init( &tmp );
    336         error = FT_Bitmap_Convert( library, bitmap, &tmp, 1 );
    337         if ( error )
    338           return error;
    339 
    340         FT_Bitmap_Done( library, bitmap );
    341         *bitmap = tmp;
    342       }
    343       break;
    344 
    345     case FT_PIXEL_MODE_MONO:
    346       if ( xstr > 8 )
    347         xstr = 8;
    348       break;
    349 
    350     case FT_PIXEL_MODE_LCD:
    351       xstr *= 3;
    352       break;
    353 
    354     case FT_PIXEL_MODE_LCD_V:
    355       ystr *= 3;
    356       break;
    357 
    358     case FT_PIXEL_MODE_BGRA:
    359       /* We don't embolden color glyphs. */
    360       return FT_Err_Ok;
    361     }
    362 
    363     error = ft_bitmap_assure_buffer( library->memory, bitmap,
    364                                      (FT_UInt)xstr, (FT_UInt)ystr );
    365     if ( error )
    366       return error;
    367 
    368     /* take care of bitmap flow */
    369     pitch = bitmap->pitch;
    370     if ( pitch > 0 )
    371       p = bitmap->buffer + pitch * ystr;
    372     else
    373     {
    374       pitch = -pitch;
    375       p = bitmap->buffer + (FT_UInt)pitch * ( bitmap->rows - 1 );
    376     }
    377 
    378     /* for each row */
    379     for ( y = 0; y < bitmap->rows; y++ )
    380     {
    381       /*
    382        * Horizontally:
    383        *
    384        * From the last pixel on, make each pixel or'ed with the
    385        * `xstr' pixels before it.
    386        */
    387       for ( x = pitch - 1; x >= 0; x-- )
    388       {
    389         unsigned char  tmp;
    390 
    391 
    392         tmp = p[x];
    393         for ( i = 1; i <= xstr; i++ )
    394         {
    395           if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
    396           {
    397             p[x] |= tmp >> i;
    398 
    399             /* the maximum value of 8 for `xstr' comes from here */
    400             if ( x > 0 )
    401               p[x] |= p[x - 1] << ( 8 - i );
    402 
    403 #if 0
    404             if ( p[x] == 0xFF )
    405               break;
    406 #endif
    407           }
    408           else
    409           {
    410             if ( x - i >= 0 )
    411             {
    412               if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
    413               {
    414                 p[x] = (unsigned char)( bitmap->num_grays - 1 );
    415                 break;
    416               }
    417               else
    418               {
    419                 p[x] = (unsigned char)( p[x] + p[x - i] );
    420                 if ( p[x] == bitmap->num_grays - 1 )
    421                   break;
    422               }
    423             }
    424             else
    425               break;
    426           }
    427         }
    428       }
    429 
    430       /*
    431        * Vertically:
    432        *
    433        * Make the above `ystr' rows or'ed with it.
    434        */
    435       for ( x = 1; x <= ystr; x++ )
    436       {
    437         unsigned char*  q;
    438 
    439 
    440         q = p - bitmap->pitch * x;
    441         for ( i = 0; i < pitch; i++ )
    442           q[i] |= p[i];
    443       }
    444 
    445       p += bitmap->pitch;
    446     }
    447 
    448     bitmap->width += (FT_UInt)xstr;
    449     bitmap->rows += (FT_UInt)ystr;
    450 
    451     return FT_Err_Ok;
    452   }
    453 
    454 
    455   static FT_Byte
    456   ft_gray_for_premultiplied_srgb_bgra( const FT_Byte*  bgra )
    457   {
    458     FT_UInt  a = bgra[3];
    459     FT_UInt  l;
    460 
    461 
    462     /* Short-circuit transparent color to avoid division by zero. */
    463     if ( !a )
    464       return 0;
    465 
    466     /*
    467      * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722
    468      * coefficients for RGB channels *on the linear colors*.
    469      * A gamma of 2.2 is fair to assume.  And then, we need to
    470      * undo the premultiplication too.
    471      *
    472      *   https://accessibility.kde.org/hsl-adjusted.php
    473      *
    474      * We do the computation with integers only, applying a gamma of 2.0.
    475      * We guarantee 32-bit arithmetic to avoid overflow but the resulting
    476      * luminosity fits into 16 bits.
    477      *
    478      */
    479 
    480     l = (  4732UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] +
    481           46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] +
    482           13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2] ) >> 16;
    483 
    484     /*
    485      * Final transparency can be determined as follows.
    486      *
    487      * - If alpha is zero, we want 0.
    488      * - If alpha is zero and luminosity is zero, we want 255.
    489      * - If alpha is zero and luminosity is one, we want 0.
    490      *
    491      * So the formula is a * (1 - l) = a - l * a.
    492      *
    493      * We still need to undo premultiplication by dividing l by a*a.
    494      *
    495      */
    496 
    497     return (FT_Byte)( a - l / a );
    498   }
    499 
    500 
    501   /* documentation is in ftbitmap.h */
    502 
    503   FT_EXPORT_DEF( FT_Error )
    504   FT_Bitmap_Convert( FT_Library        library,
    505                      const FT_Bitmap  *source,
    506                      FT_Bitmap        *target,
    507                      FT_Int            alignment )
    508   {
    509     FT_Error   error = FT_Err_Ok;
    510     FT_Memory  memory;
    511 
    512     FT_Byte*  s;
    513     FT_Byte*  t;
    514 
    515 
    516     if ( !library )
    517       return FT_THROW( Invalid_Library_Handle );
    518 
    519     if ( !source || !target )
    520       return FT_THROW( Invalid_Argument );
    521 
    522     memory = library->memory;
    523 
    524     switch ( source->pixel_mode )
    525     {
    526     case FT_PIXEL_MODE_MONO:
    527     case FT_PIXEL_MODE_GRAY:
    528     case FT_PIXEL_MODE_GRAY2:
    529     case FT_PIXEL_MODE_GRAY4:
    530     case FT_PIXEL_MODE_LCD:
    531     case FT_PIXEL_MODE_LCD_V:
    532     case FT_PIXEL_MODE_BGRA:
    533       {
    534         FT_Int    pad, old_target_pitch, target_pitch;
    535         FT_ULong  old_size;
    536 
    537 
    538         old_target_pitch = target->pitch;
    539         if ( old_target_pitch < 0 )
    540           old_target_pitch = -old_target_pitch;
    541 
    542         old_size = target->rows * (FT_UInt)old_target_pitch;
    543 
    544         target->pixel_mode = FT_PIXEL_MODE_GRAY;
    545         target->rows       = source->rows;
    546         target->width      = source->width;
    547 
    548         pad = 0;
    549         if ( alignment > 0 )
    550         {
    551           pad = (FT_Int)source->width % alignment;
    552           if ( pad != 0 )
    553             pad = alignment - pad;
    554         }
    555 
    556         target_pitch = (FT_Int)source->width + pad;
    557 
    558         if ( target_pitch > 0                                               &&
    559              (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch )
    560           return FT_THROW( Invalid_Argument );
    561 
    562         if ( FT_QREALLOC( target->buffer,
    563                           old_size, target->rows * (FT_UInt)target_pitch ) )
    564           return error;
    565 
    566         target->pitch = target->pitch < 0 ? -target_pitch : target_pitch;
    567       }
    568       break;
    569 
    570     default:
    571       error = FT_THROW( Invalid_Argument );
    572     }
    573 
    574     s = source->buffer;
    575     t = target->buffer;
    576 
    577     /* take care of bitmap flow */
    578     if ( source->pitch < 0 )
    579       s -= source->pitch * (FT_Int)( source->rows - 1 );
    580     if ( target->pitch < 0 )
    581       t -= target->pitch * (FT_Int)( target->rows - 1 );
    582 
    583     switch ( source->pixel_mode )
    584     {
    585     case FT_PIXEL_MODE_MONO:
    586       {
    587         FT_UInt  i;
    588 
    589 
    590         target->num_grays = 2;
    591 
    592         for ( i = source->rows; i > 0; i-- )
    593         {
    594           FT_Byte*  ss = s;
    595           FT_Byte*  tt = t;
    596           FT_UInt   j;
    597 
    598 
    599           /* get the full bytes */
    600           for ( j = source->width >> 3; j > 0; j-- )
    601           {
    602             FT_Int  val = ss[0]; /* avoid a byte->int cast on each line */
    603 
    604 
    605             tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
    606             tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
    607             tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
    608             tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
    609             tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
    610             tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
    611             tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
    612             tt[7] = (FT_Byte)(   val & 0x01 );
    613 
    614             tt += 8;
    615             ss += 1;
    616           }
    617 
    618           /* get remaining pixels (if any) */
    619           j = source->width & 7;
    620           if ( j > 0 )
    621           {
    622             FT_Int  val = *ss;
    623 
    624 
    625             for ( ; j > 0; j-- )
    626             {
    627               tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
    628               val <<= 1;
    629               tt   += 1;
    630             }
    631           }
    632 
    633           s += source->pitch;
    634           t += target->pitch;
    635         }
    636       }
    637       break;
    638 
    639 
    640     case FT_PIXEL_MODE_GRAY:
    641     case FT_PIXEL_MODE_LCD:
    642     case FT_PIXEL_MODE_LCD_V:
    643       {
    644         FT_UInt  width = source->width;
    645         FT_UInt  i;
    646 
    647 
    648         target->num_grays = 256;
    649 
    650         for ( i = source->rows; i > 0; i-- )
    651         {
    652           FT_ARRAY_COPY( t, s, width );
    653 
    654           s += source->pitch;
    655           t += target->pitch;
    656         }
    657       }
    658       break;
    659 
    660 
    661     case FT_PIXEL_MODE_GRAY2:
    662       {
    663         FT_UInt  i;
    664 
    665 
    666         target->num_grays = 4;
    667 
    668         for ( i = source->rows; i > 0; i-- )
    669         {
    670           FT_Byte*  ss = s;
    671           FT_Byte*  tt = t;
    672           FT_UInt   j;
    673 
    674 
    675           /* get the full bytes */
    676           for ( j = source->width >> 2; j > 0; j-- )
    677           {
    678             FT_Int  val = ss[0];
    679 
    680 
    681             tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
    682             tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
    683             tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
    684             tt[3] = (FT_Byte)( ( val & 0x03 ) );
    685 
    686             ss += 1;
    687             tt += 4;
    688           }
    689 
    690           j = source->width & 3;
    691           if ( j > 0 )
    692           {
    693             FT_Int  val = ss[0];
    694 
    695 
    696             for ( ; j > 0; j-- )
    697             {
    698               tt[0]  = (FT_Byte)( ( val & 0xC0 ) >> 6 );
    699               val  <<= 2;
    700               tt    += 1;
    701             }
    702           }
    703 
    704           s += source->pitch;
    705           t += target->pitch;
    706         }
    707       }
    708       break;
    709 
    710 
    711     case FT_PIXEL_MODE_GRAY4:
    712       {
    713         FT_UInt  i;
    714 
    715 
    716         target->num_grays = 16;
    717 
    718         for ( i = source->rows; i > 0; i-- )
    719         {
    720           FT_Byte*  ss = s;
    721           FT_Byte*  tt = t;
    722           FT_UInt   j;
    723 
    724 
    725           /* get the full bytes */
    726           for ( j = source->width >> 1; j > 0; j-- )
    727           {
    728             FT_Int  val = ss[0];
    729 
    730 
    731             tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
    732             tt[1] = (FT_Byte)( ( val & 0x0F ) );
    733 
    734             ss += 1;
    735             tt += 2;
    736           }
    737 
    738           if ( source->width & 1 )
    739             tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
    740 
    741           s += source->pitch;
    742           t += target->pitch;
    743         }
    744       }
    745       break;
    746 
    747 
    748     case FT_PIXEL_MODE_BGRA:
    749       {
    750         FT_UInt  i;
    751 
    752 
    753         target->num_grays = 256;
    754 
    755         for ( i = source->rows; i > 0; i-- )
    756         {
    757           FT_Byte*  ss = s;
    758           FT_Byte*  tt = t;
    759           FT_UInt   j;
    760 
    761 
    762           for ( j = source->width; j > 0; j-- )
    763           {
    764             tt[0] = ft_gray_for_premultiplied_srgb_bgra( ss );
    765 
    766             ss += 4;
    767             tt += 1;
    768           }
    769 
    770           s += source->pitch;
    771           t += target->pitch;
    772         }
    773       }
    774       break;
    775 
    776     default:
    777       ;
    778     }
    779 
    780     return error;
    781   }
    782 
    783 
    784   /* documentation is in ftbitmap.h */
    785 
    786   FT_EXPORT_DEF( FT_Error )
    787   FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot  slot )
    788   {
    789     if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP   &&
    790          !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
    791     {
    792       FT_Bitmap  bitmap;
    793       FT_Error   error;
    794 
    795 
    796       FT_Bitmap_Init( &bitmap );
    797       error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );
    798       if ( error )
    799         return error;
    800 
    801       slot->bitmap = bitmap;
    802       slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
    803     }
    804 
    805     return FT_Err_Ok;
    806   }
    807 
    808 
    809   /* documentation is in ftbitmap.h */
    810 
    811   FT_EXPORT_DEF( FT_Error )
    812   FT_Bitmap_Done( FT_Library  library,
    813                   FT_Bitmap  *bitmap )
    814   {
    815     FT_Memory  memory;
    816 
    817 
    818     if ( !library )
    819       return FT_THROW( Invalid_Library_Handle );
    820 
    821     if ( !bitmap )
    822       return FT_THROW( Invalid_Argument );
    823 
    824     memory = library->memory;
    825 
    826     FT_FREE( bitmap->buffer );
    827     *bitmap = null_bitmap;
    828 
    829     return FT_Err_Ok;
    830   }
    831 
    832 
    833 /* END */
    834