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 */