1 /**************************************************************************** 2 * 3 * pfrsbit.c 4 * 5 * FreeType PFR bitmap loader (body). 6 * 7 * Copyright 2002-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 "pfrsbit.h" 20 #include "pfrload.h" 21 #include FT_INTERNAL_DEBUG_H 22 #include FT_INTERNAL_STREAM_H 23 24 #include "pfrerror.h" 25 26 #undef FT_COMPONENT 27 #define FT_COMPONENT trace_pfr 28 29 30 /*************************************************************************/ 31 /*************************************************************************/ 32 /***** *****/ 33 /***** PFR BIT WRITER *****/ 34 /***** *****/ 35 /*************************************************************************/ 36 /*************************************************************************/ 37 38 typedef struct PFR_BitWriter_ 39 { 40 FT_Byte* line; /* current line start */ 41 FT_Int pitch; /* line size in bytes */ 42 FT_UInt width; /* width in pixels/bits */ 43 FT_UInt rows; /* number of remaining rows to scan */ 44 FT_UInt total; /* total number of bits to draw */ 45 46 } PFR_BitWriterRec, *PFR_BitWriter; 47 48 49 static void pfr_bitwriter_init(PFR_BitWriter writer,FT_Bitmap * target,FT_Bool decreasing)50 pfr_bitwriter_init( PFR_BitWriter writer, 51 FT_Bitmap* target, 52 FT_Bool decreasing ) 53 { 54 writer->line = target->buffer; 55 writer->pitch = target->pitch; 56 writer->width = target->width; 57 writer->rows = target->rows; 58 writer->total = writer->width * writer->rows; 59 60 if ( !decreasing ) 61 { 62 writer->line += writer->pitch * (FT_Int)( target->rows - 1 ); 63 writer->pitch = -writer->pitch; 64 } 65 } 66 67 68 static void pfr_bitwriter_decode_bytes(PFR_BitWriter writer,FT_Byte * p,FT_Byte * limit)69 pfr_bitwriter_decode_bytes( PFR_BitWriter writer, 70 FT_Byte* p, 71 FT_Byte* limit ) 72 { 73 FT_UInt n, reload; 74 FT_UInt left = writer->width; 75 FT_Byte* cur = writer->line; 76 FT_UInt mask = 0x80; 77 FT_UInt val = 0; 78 FT_UInt c = 0; 79 80 81 n = (FT_UInt)( limit - p ) * 8; 82 if ( n > writer->total ) 83 n = writer->total; 84 85 reload = n & 7; 86 87 for ( ; n > 0; n-- ) 88 { 89 if ( ( n & 7 ) == reload ) 90 val = *p++; 91 92 if ( val & 0x80 ) 93 c |= mask; 94 95 val <<= 1; 96 mask >>= 1; 97 98 if ( --left <= 0 ) 99 { 100 cur[0] = (FT_Byte)c; 101 left = writer->width; 102 mask = 0x80; 103 104 writer->line += writer->pitch; 105 cur = writer->line; 106 c = 0; 107 } 108 else if ( mask == 0 ) 109 { 110 cur[0] = (FT_Byte)c; 111 mask = 0x80; 112 c = 0; 113 cur++; 114 } 115 } 116 117 if ( mask != 0x80 ) 118 cur[0] = (FT_Byte)c; 119 } 120 121 122 static void pfr_bitwriter_decode_rle1(PFR_BitWriter writer,FT_Byte * p,FT_Byte * limit)123 pfr_bitwriter_decode_rle1( PFR_BitWriter writer, 124 FT_Byte* p, 125 FT_Byte* limit ) 126 { 127 FT_Int phase, count, counts[2]; 128 FT_UInt n, reload; 129 FT_UInt left = writer->width; 130 FT_Byte* cur = writer->line; 131 FT_UInt mask = 0x80; 132 FT_UInt c = 0; 133 134 135 n = writer->total; 136 137 phase = 1; 138 counts[0] = 0; 139 counts[1] = 0; 140 count = 0; 141 reload = 1; 142 143 for ( ; n > 0; n-- ) 144 { 145 if ( reload ) 146 { 147 do 148 { 149 if ( phase ) 150 { 151 FT_Int v; 152 153 154 if ( p >= limit ) 155 break; 156 157 v = *p++; 158 counts[0] = v >> 4; 159 counts[1] = v & 15; 160 phase = 0; 161 count = counts[0]; 162 } 163 else 164 { 165 phase = 1; 166 count = counts[1]; 167 } 168 169 } while ( count == 0 ); 170 } 171 172 if ( phase ) 173 c |= mask; 174 175 mask >>= 1; 176 177 if ( --left <= 0 ) 178 { 179 cur[0] = (FT_Byte)c; 180 left = writer->width; 181 mask = 0x80; 182 183 writer->line += writer->pitch; 184 cur = writer->line; 185 c = 0; 186 } 187 else if ( mask == 0 ) 188 { 189 cur[0] = (FT_Byte)c; 190 mask = 0x80; 191 c = 0; 192 cur++; 193 } 194 195 reload = ( --count <= 0 ); 196 } 197 198 if ( mask != 0x80 ) 199 cur[0] = (FT_Byte) c; 200 } 201 202 203 static void pfr_bitwriter_decode_rle2(PFR_BitWriter writer,FT_Byte * p,FT_Byte * limit)204 pfr_bitwriter_decode_rle2( PFR_BitWriter writer, 205 FT_Byte* p, 206 FT_Byte* limit ) 207 { 208 FT_Int phase, count; 209 FT_UInt n, reload; 210 FT_UInt left = writer->width; 211 FT_Byte* cur = writer->line; 212 FT_UInt mask = 0x80; 213 FT_UInt c = 0; 214 215 216 n = writer->total; 217 218 phase = 1; 219 count = 0; 220 reload = 1; 221 222 for ( ; n > 0; n-- ) 223 { 224 if ( reload ) 225 { 226 do 227 { 228 if ( p >= limit ) 229 break; 230 231 count = *p++; 232 phase = phase ^ 1; 233 234 } while ( count == 0 ); 235 } 236 237 if ( phase ) 238 c |= mask; 239 240 mask >>= 1; 241 242 if ( --left <= 0 ) 243 { 244 cur[0] = (FT_Byte)c; 245 c = 0; 246 mask = 0x80; 247 left = writer->width; 248 249 writer->line += writer->pitch; 250 cur = writer->line; 251 } 252 else if ( mask == 0 ) 253 { 254 cur[0] = (FT_Byte)c; 255 c = 0; 256 mask = 0x80; 257 cur++; 258 } 259 260 reload = ( --count <= 0 ); 261 } 262 263 if ( mask != 0x80 ) 264 cur[0] = (FT_Byte) c; 265 } 266 267 268 /*************************************************************************/ 269 /*************************************************************************/ 270 /***** *****/ 271 /***** BITMAP DATA DECODING *****/ 272 /***** *****/ 273 /*************************************************************************/ 274 /*************************************************************************/ 275 276 static void pfr_lookup_bitmap_data(FT_Byte * base,FT_Byte * limit,FT_UInt count,FT_UInt * flags,FT_UInt char_code,FT_ULong * found_offset,FT_ULong * found_size)277 pfr_lookup_bitmap_data( FT_Byte* base, 278 FT_Byte* limit, 279 FT_UInt count, 280 FT_UInt* flags, 281 FT_UInt char_code, 282 FT_ULong* found_offset, 283 FT_ULong* found_size ) 284 { 285 FT_UInt min, max, char_len; 286 FT_Bool two = FT_BOOL( *flags & PFR_BITMAP_2BYTE_CHARCODE ); 287 FT_Byte* buff; 288 289 290 char_len = 4; 291 if ( two ) 292 char_len += 1; 293 if ( *flags & PFR_BITMAP_2BYTE_SIZE ) 294 char_len += 1; 295 if ( *flags & PFR_BITMAP_3BYTE_OFFSET ) 296 char_len += 1; 297 298 if ( !( *flags & PFR_BITMAP_CHARCODES_VALIDATED ) ) 299 { 300 FT_Byte* p; 301 FT_Byte* lim; 302 FT_UInt code; 303 FT_Long prev_code; 304 305 306 *flags |= PFR_BITMAP_VALID_CHARCODES; 307 prev_code = -1; 308 lim = base + count * char_len; 309 310 if ( lim > limit ) 311 { 312 FT_TRACE0(( "pfr_lookup_bitmap_data:" 313 " number of bitmap records too large,\n" 314 " " 315 " thus ignoring all bitmaps in this strike\n" )); 316 *flags &= ~PFR_BITMAP_VALID_CHARCODES; 317 } 318 else 319 { 320 /* check whether records are sorted by code */ 321 for ( p = base; p < lim; p += char_len ) 322 { 323 if ( two ) 324 code = FT_PEEK_USHORT( p ); 325 else 326 code = *p; 327 328 if ( (FT_Long)code <= prev_code ) 329 { 330 FT_TRACE0(( "pfr_lookup_bitmap_data:" 331 " bitmap records are not sorted,\n" 332 " " 333 " thus ignoring all bitmaps in this strike\n" )); 334 *flags &= ~PFR_BITMAP_VALID_CHARCODES; 335 break; 336 } 337 338 prev_code = code; 339 } 340 } 341 342 *flags |= PFR_BITMAP_CHARCODES_VALIDATED; 343 } 344 345 /* ignore bitmaps in case table is not valid */ 346 /* (this might be sanitized, but PFR is dead...) */ 347 if ( !( *flags & PFR_BITMAP_VALID_CHARCODES ) ) 348 goto Fail; 349 350 min = 0; 351 max = count; 352 353 /* binary search */ 354 while ( min < max ) 355 { 356 FT_UInt mid, code; 357 358 359 mid = ( min + max ) >> 1; 360 buff = base + mid * char_len; 361 362 if ( two ) 363 code = PFR_NEXT_USHORT( buff ); 364 else 365 code = PFR_NEXT_BYTE( buff ); 366 367 if ( char_code < code ) 368 max = mid; 369 else if ( char_code > code ) 370 min = mid + 1; 371 else 372 goto Found_It; 373 } 374 375 Fail: 376 /* Not found */ 377 *found_size = 0; 378 *found_offset = 0; 379 return; 380 381 Found_It: 382 if ( *flags & PFR_BITMAP_2BYTE_SIZE ) 383 *found_size = PFR_NEXT_USHORT( buff ); 384 else 385 *found_size = PFR_NEXT_BYTE( buff ); 386 387 if ( *flags & PFR_BITMAP_3BYTE_OFFSET ) 388 *found_offset = PFR_NEXT_ULONG( buff ); 389 else 390 *found_offset = PFR_NEXT_USHORT( buff ); 391 } 392 393 394 /* load bitmap metrics. `*padvance' must be set to the default value */ 395 /* before calling this function */ 396 /* */ 397 static FT_Error pfr_load_bitmap_metrics(FT_Byte ** pdata,FT_Byte * limit,FT_Long scaled_advance,FT_Long * axpos,FT_Long * aypos,FT_UInt * axsize,FT_UInt * aysize,FT_Long * aadvance,FT_UInt * aformat)398 pfr_load_bitmap_metrics( FT_Byte** pdata, 399 FT_Byte* limit, 400 FT_Long scaled_advance, 401 FT_Long *axpos, 402 FT_Long *aypos, 403 FT_UInt *axsize, 404 FT_UInt *aysize, 405 FT_Long *aadvance, 406 FT_UInt *aformat ) 407 { 408 FT_Error error = FT_Err_Ok; 409 FT_Byte flags; 410 FT_Byte b; 411 FT_Byte* p = *pdata; 412 FT_Long xpos, ypos, advance; 413 FT_UInt xsize, ysize; 414 415 416 PFR_CHECK( 1 ); 417 flags = PFR_NEXT_BYTE( p ); 418 419 xpos = 0; 420 ypos = 0; 421 xsize = 0; 422 ysize = 0; 423 advance = 0; 424 425 switch ( flags & 3 ) 426 { 427 case 0: 428 PFR_CHECK( 1 ); 429 b = PFR_NEXT_BYTE( p ); 430 xpos = (FT_Char)b >> 4; 431 ypos = ( (FT_Char)( b << 4 ) ) >> 4; 432 break; 433 434 case 1: 435 PFR_CHECK( 2 ); 436 xpos = PFR_NEXT_INT8( p ); 437 ypos = PFR_NEXT_INT8( p ); 438 break; 439 440 case 2: 441 PFR_CHECK( 4 ); 442 xpos = PFR_NEXT_SHORT( p ); 443 ypos = PFR_NEXT_SHORT( p ); 444 break; 445 446 case 3: 447 PFR_CHECK( 6 ); 448 xpos = PFR_NEXT_LONG( p ); 449 ypos = PFR_NEXT_LONG( p ); 450 break; 451 452 default: 453 ; 454 } 455 456 flags >>= 2; 457 switch ( flags & 3 ) 458 { 459 case 0: 460 /* blank image */ 461 xsize = 0; 462 ysize = 0; 463 break; 464 465 case 1: 466 PFR_CHECK( 1 ); 467 b = PFR_NEXT_BYTE( p ); 468 xsize = ( b >> 4 ) & 0xF; 469 ysize = b & 0xF; 470 break; 471 472 case 2: 473 PFR_CHECK( 2 ); 474 xsize = PFR_NEXT_BYTE( p ); 475 ysize = PFR_NEXT_BYTE( p ); 476 break; 477 478 case 3: 479 PFR_CHECK( 4 ); 480 xsize = PFR_NEXT_USHORT( p ); 481 ysize = PFR_NEXT_USHORT( p ); 482 break; 483 484 default: 485 ; 486 } 487 488 flags >>= 2; 489 switch ( flags & 3 ) 490 { 491 case 0: 492 advance = scaled_advance; 493 break; 494 495 case 1: 496 PFR_CHECK( 1 ); 497 advance = PFR_NEXT_INT8( p ) * 256; 498 break; 499 500 case 2: 501 PFR_CHECK( 2 ); 502 advance = PFR_NEXT_SHORT( p ); 503 break; 504 505 case 3: 506 PFR_CHECK( 3 ); 507 advance = PFR_NEXT_LONG( p ); 508 break; 509 510 default: 511 ; 512 } 513 514 *axpos = xpos; 515 *aypos = ypos; 516 *axsize = xsize; 517 *aysize = ysize; 518 *aadvance = advance; 519 *aformat = flags >> 2; 520 *pdata = p; 521 522 Exit: 523 return error; 524 525 Too_Short: 526 error = FT_THROW( Invalid_Table ); 527 FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" )); 528 goto Exit; 529 } 530 531 532 static FT_Error pfr_load_bitmap_bits(FT_Byte * p,FT_Byte * limit,FT_UInt format,FT_Bool decreasing,FT_Bitmap * target)533 pfr_load_bitmap_bits( FT_Byte* p, 534 FT_Byte* limit, 535 FT_UInt format, 536 FT_Bool decreasing, 537 FT_Bitmap* target ) 538 { 539 FT_Error error = FT_Err_Ok; 540 PFR_BitWriterRec writer; 541 542 543 if ( target->rows > 0 && target->width > 0 ) 544 { 545 pfr_bitwriter_init( &writer, target, decreasing ); 546 547 switch ( format ) 548 { 549 case 0: /* packed bits */ 550 pfr_bitwriter_decode_bytes( &writer, p, limit ); 551 break; 552 553 case 1: /* RLE1 */ 554 pfr_bitwriter_decode_rle1( &writer, p, limit ); 555 break; 556 557 case 2: /* RLE2 */ 558 pfr_bitwriter_decode_rle2( &writer, p, limit ); 559 break; 560 561 default: 562 ; 563 } 564 } 565 566 return error; 567 } 568 569 570 /*************************************************************************/ 571 /*************************************************************************/ 572 /***** *****/ 573 /***** BITMAP LOADING *****/ 574 /***** *****/ 575 /*************************************************************************/ 576 /*************************************************************************/ 577 578 FT_LOCAL( FT_Error ) pfr_slot_load_bitmap(PFR_Slot glyph,PFR_Size size,FT_UInt glyph_index,FT_Bool metrics_only)579 pfr_slot_load_bitmap( PFR_Slot glyph, 580 PFR_Size size, 581 FT_UInt glyph_index, 582 FT_Bool metrics_only ) 583 { 584 FT_Error error; 585 PFR_Face face = (PFR_Face) glyph->root.face; 586 FT_Stream stream = face->root.stream; 587 PFR_PhyFont phys = &face->phy_font; 588 FT_ULong gps_offset; 589 FT_ULong gps_size; 590 PFR_Char character; 591 PFR_Strike strike; 592 593 594 character = &phys->chars[glyph_index]; 595 596 /* look up a bitmap strike corresponding to the current */ 597 /* character dimensions */ 598 { 599 FT_UInt n; 600 601 602 strike = phys->strikes; 603 for ( n = 0; n < phys->num_strikes; n++ ) 604 { 605 if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem && 606 strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem ) 607 goto Found_Strike; 608 609 strike++; 610 } 611 612 /* couldn't find it */ 613 return FT_THROW( Invalid_Argument ); 614 } 615 616 Found_Strike: 617 618 /* now look up the glyph's position within the file */ 619 { 620 FT_UInt char_len; 621 622 623 char_len = 4; 624 if ( strike->flags & PFR_BITMAP_2BYTE_CHARCODE ) 625 char_len += 1; 626 if ( strike->flags & PFR_BITMAP_2BYTE_SIZE ) 627 char_len += 1; 628 if ( strike->flags & PFR_BITMAP_3BYTE_OFFSET ) 629 char_len += 1; 630 631 /* access data directly in the frame to speed lookups */ 632 if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) || 633 FT_FRAME_ENTER( char_len * strike->num_bitmaps ) ) 634 goto Exit; 635 636 pfr_lookup_bitmap_data( stream->cursor, 637 stream->limit, 638 strike->num_bitmaps, 639 &strike->flags, 640 character->char_code, 641 &gps_offset, 642 &gps_size ); 643 644 FT_FRAME_EXIT(); 645 646 if ( gps_size == 0 ) 647 { 648 /* could not find a bitmap program string for this glyph */ 649 error = FT_THROW( Invalid_Argument ); 650 goto Exit; 651 } 652 } 653 654 /* get the bitmap metrics */ 655 { 656 FT_Long xpos = 0, ypos = 0, advance = 0; 657 FT_UInt xsize = 0, ysize = 0, format = 0; 658 FT_Byte* p; 659 660 661 /* compute linear advance */ 662 advance = character->advance; 663 if ( phys->metrics_resolution != phys->outline_resolution ) 664 advance = FT_MulDiv( advance, 665 (FT_Long)phys->outline_resolution, 666 (FT_Long)phys->metrics_resolution ); 667 668 glyph->root.linearHoriAdvance = advance; 669 670 /* compute default advance, i.e., scaled advance; this can be */ 671 /* overridden in the bitmap header of certain glyphs */ 672 advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8, 673 character->advance, 674 (FT_Long)phys->metrics_resolution ); 675 676 if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) || 677 FT_FRAME_ENTER( gps_size ) ) 678 goto Exit; 679 680 p = stream->cursor; 681 error = pfr_load_bitmap_metrics( &p, stream->limit, 682 advance, 683 &xpos, &ypos, 684 &xsize, &ysize, 685 &advance, &format ); 686 if ( error ) 687 goto Exit1; 688 689 /* 690 * Before allocating the target bitmap, we check whether the given 691 * bitmap dimensions are valid, depending on the image format. 692 * 693 * Format 0: We have a stream of pixels (with 8 pixels per byte). 694 * 695 * (xsize * ysize + 7) / 8 <= gps_size 696 * 697 * Format 1: Run-length encoding; the high nibble holds the number of 698 * white bits, the low nibble the number of black bits. In 699 * other words, a single byte can represent at most 15 700 * pixels. 701 * 702 * xsize * ysize <= 15 * gps_size 703 * 704 * Format 2: Run-length encoding; the high byte holds the number of 705 * white bits, the low byte the number of black bits. In 706 * other words, two bytes can represent at most 255 pixels. 707 * 708 * xsize * ysize <= 255 * (gps_size + 1) / 2 709 */ 710 switch ( format ) 711 { 712 case 0: 713 if ( ( (FT_ULong)xsize * ysize + 7 ) / 8 > gps_size ) 714 error = FT_THROW( Invalid_Table ); 715 break; 716 case 1: 717 if ( (FT_ULong)xsize * ysize > 15 * gps_size ) 718 error = FT_THROW( Invalid_Table ); 719 break; 720 case 2: 721 if ( (FT_ULong)xsize * ysize > 255 * ( ( gps_size + 1 ) / 2 ) ) 722 error = FT_THROW( Invalid_Table ); 723 break; 724 default: 725 FT_ERROR(( "pfr_slot_load_bitmap: invalid image type\n" )); 726 error = FT_THROW( Invalid_Table ); 727 } 728 729 if ( error ) 730 { 731 if ( FT_ERR_EQ( error, Invalid_Table ) ) 732 FT_ERROR(( "pfr_slot_load_bitmap: invalid bitmap dimensions\n" )); 733 goto Exit1; 734 } 735 736 /* 737 * XXX: on 16bit systems we return an error for huge bitmaps 738 * that cause size truncation, because truncated 739 * size properties make bitmap glyphs broken. 740 */ 741 if ( xpos > FT_INT_MAX || 742 xpos < FT_INT_MIN || 743 ysize > FT_INT_MAX || 744 ypos > FT_INT_MAX - (FT_Long)ysize || 745 ypos + (FT_Long)ysize < FT_INT_MIN ) 746 { 747 FT_TRACE1(( "pfr_slot_load_bitmap:" )); 748 FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n", 749 xpos, ypos )); 750 error = FT_THROW( Invalid_Pixel_Size ); 751 } 752 753 if ( !error ) 754 { 755 glyph->root.format = FT_GLYPH_FORMAT_BITMAP; 756 757 /* Set up glyph bitmap and metrics */ 758 759 /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */ 760 glyph->root.bitmap.width = xsize; 761 glyph->root.bitmap.rows = ysize; 762 glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3; 763 glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO; 764 765 /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */ 766 glyph->root.metrics.width = (FT_Pos)xsize << 6; 767 glyph->root.metrics.height = (FT_Pos)ysize << 6; 768 glyph->root.metrics.horiBearingX = xpos * 64; 769 glyph->root.metrics.horiBearingY = ypos * 64; 770 glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) ); 771 glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1; 772 glyph->root.metrics.vertBearingY = 0; 773 glyph->root.metrics.vertAdvance = size->root.metrics.height; 774 775 /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */ 776 glyph->root.bitmap_left = (FT_Int)xpos; 777 glyph->root.bitmap_top = (FT_Int)( ypos + (FT_Long)ysize ); 778 779 if ( metrics_only ) 780 goto Exit1; 781 782 /* Allocate and read bitmap data */ 783 { 784 FT_ULong len = (FT_ULong)glyph->root.bitmap.pitch * ysize; 785 786 787 error = ft_glyphslot_alloc_bitmap( &glyph->root, len ); 788 if ( !error ) 789 error = pfr_load_bitmap_bits( 790 p, 791 stream->limit, 792 format, 793 FT_BOOL( face->header.color_flags & 794 PFR_FLAG_INVERT_BITMAP ), 795 &glyph->root.bitmap ); 796 } 797 } 798 799 Exit1: 800 FT_FRAME_EXIT(); 801 } 802 803 Exit: 804 return error; 805 } 806 807 808 /* END */ 809