static FT_Error classic_kern_validate( FT_Face face, FT_UInt ckern_flags, FT_Bytes* ckern_table ) { FT_Memory volatile memory = FT_FACE_MEMORY( face ); FT_Byte* volatile ckern = NULL; FT_ULong len_ckern = 0; /* without volatile on `error' GCC 4.1.1. emits: */ /* warning: variable 'error' might be clobbered by 'longjmp' or 'vfork' */ /* this warning seems spurious but --- */ FT_Error volatile error; FT_ValidatorRec volatile valid; *ckern_table = NULL; error = gxv_load_table( face, TTAG_kern, &ckern, &len_ckern ); if ( error ) goto Exit; if ( ckern ) { ft_validator_init( &valid, ckern, ckern + len_ckern, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) gxv_kern_validate_classic( ckern, face, ckern_flags & FT_VALIDATE_CKERN, &valid ); error = valid.error; if ( error ) goto Exit; } *ckern_table = ckern; Exit: if ( error ) FT_FREE( ckern ); return error; }
Load_SBit_Png( FT_GlyphSlot slot, FT_Int x_offset, FT_Int y_offset, FT_Int pix_bits, TT_SBit_Metrics metrics, FT_Memory memory, FT_Byte* data, FT_UInt png_len, FT_Bool populate_map_and_metrics ) { FT_Bitmap *map = &slot->bitmap; FT_Error error = FT_Err_Ok; FT_StreamRec stream; png_structp png; png_infop info; png_uint_32 imgWidth, imgHeight; int bitdepth, color_type, interlace; FT_Int i; png_byte* *rows = NULL; /* pacify compiler */ if ( x_offset < 0 || y_offset < 0 ) { error = FT_THROW( Invalid_Argument ); goto Exit; } if ( !populate_map_and_metrics && ( x_offset + metrics->width > map->width || y_offset + metrics->height > map->rows || pix_bits != 32 || map->pixel_mode != FT_PIXEL_MODE_BGRA ) ) { error = FT_THROW( Invalid_Argument ); goto Exit; } FT_Stream_OpenMemory( &stream, data, png_len ); png = png_create_read_struct( PNG_LIBPNG_VER_STRING, &error, error_callback, warning_callback ); if ( !png ) { error = FT_THROW( Out_Of_Memory ); goto Exit; } info = png_create_info_struct( png ); if ( !info ) { error = FT_THROW( Out_Of_Memory ); png_destroy_read_struct( &png, NULL, NULL ); goto Exit; } if ( ft_setjmp( png_jmpbuf( png ) ) ) { error = FT_THROW( Invalid_File_Format ); goto DestroyExit; } png_set_read_fn( png, &stream, read_data_from_FT_Stream ); png_read_info( png, info ); png_get_IHDR( png, info, &imgWidth, &imgHeight, &bitdepth, &color_type, &interlace, NULL, NULL ); if ( error || ( !populate_map_and_metrics && ( (FT_Int)imgWidth != metrics->width || (FT_Int)imgHeight != metrics->height ) ) ) goto DestroyExit; if ( populate_map_and_metrics ) { FT_Long size; metrics->width = (FT_Int)imgWidth; metrics->height = (FT_Int)imgHeight; map->width = metrics->width; map->rows = metrics->height; map->pixel_mode = FT_PIXEL_MODE_BGRA; map->pitch = map->width * 4; map->num_grays = 256; size = map->rows * map->pitch; error = ft_glyphslot_alloc_bitmap( slot, size ); if ( error ) goto DestroyExit; } /* convert palette/gray image to rgb */ if ( color_type == PNG_COLOR_TYPE_PALETTE ) png_set_palette_to_rgb( png ); /* expand gray bit depth if needed */ if ( color_type == PNG_COLOR_TYPE_GRAY ) { #if PNG_LIBPNG_VER >= 10209 png_set_expand_gray_1_2_4_to_8( png ); #else png_set_gray_1_2_4_to_8( png ); #endif } /* transform transparency to alpha */ if ( png_get_valid(png, info, PNG_INFO_tRNS ) ) png_set_tRNS_to_alpha( png ); if ( bitdepth == 16 ) png_set_strip_16( png ); if ( bitdepth < 8 ) png_set_packing( png ); /* convert grayscale to RGB */ if ( color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) png_set_gray_to_rgb( png ); if ( interlace != PNG_INTERLACE_NONE ) png_set_interlace_handling( png ); png_set_filler( png, 0xFF, PNG_FILLER_AFTER ); /* recheck header after setting EXPAND options */ png_read_update_info(png, info ); png_get_IHDR( png, info, &imgWidth, &imgHeight, &bitdepth, &color_type, &interlace, NULL, NULL ); if ( bitdepth != 8 || !( color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA ) ) { error = FT_THROW( Invalid_File_Format ); goto DestroyExit; } switch ( color_type ) { default: /* Shouldn't happen, but fall through. */ case PNG_COLOR_TYPE_RGB_ALPHA: png_set_read_user_transform_fn( png, premultiply_data ); break; case PNG_COLOR_TYPE_RGB: /* Humm, this smells. Carry on though. */ png_set_read_user_transform_fn( png, convert_bytes_to_data ); break; } if ( FT_NEW_ARRAY( rows, imgHeight ) ) { error = FT_THROW( Out_Of_Memory ); goto DestroyExit; } for ( i = 0; i < (FT_Int)imgHeight; i++ ) rows[i] = map->buffer + ( y_offset + i ) * map->pitch + x_offset * 4; png_read_image( png, rows ); FT_FREE( rows ); png_read_end( png, info ); DestroyExit: png_destroy_read_struct( &png, &info, NULL ); FT_Stream_Close( &stream ); Exit: return error; }
static FT_Error otv_validate( FT_Face volatile face, FT_UInt ot_flags, FT_Bytes *ot_base, FT_Bytes *ot_gdef, FT_Bytes *ot_gpos, FT_Bytes *ot_gsub, FT_Bytes *ot_jstf ) { FT_Error error = OTV_Err_Ok; FT_Byte* volatile base; FT_Byte* volatile gdef; FT_Byte* volatile gpos; FT_Byte* volatile gsub; FT_Byte* volatile jstf; FT_Byte* volatile math; FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; FT_ULong len_math; FT_UInt num_glyphs = (FT_UInt)face->num_glyphs; FT_ValidatorRec volatile valid; base = gdef = gpos = gsub = jstf = math = NULL; len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0; /* * XXX: OpenType tables cannot handle 32-bit glyph index, * although broken TrueType can have 32-bit glyph index. */ if ( face->num_glyphs > 0xFFFFL ) { FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08x) ", face->num_glyphs )); FT_TRACE1(( "are not handled by OpenType tables\n" )); num_glyphs = 0xFFFF; } /* load tables */ if ( ot_flags & FT_VALIDATE_BASE ) { error = otv_load_table( face, TTAG_BASE, &base, &len_base ); if ( error ) goto Exit; } if ( ot_flags & FT_VALIDATE_GDEF ) { error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef ); if ( error ) goto Exit; } if ( ot_flags & FT_VALIDATE_GPOS ) { error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos ); if ( error ) goto Exit; } if ( ot_flags & FT_VALIDATE_GSUB ) { error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub ); if ( error ) goto Exit; } if ( ot_flags & FT_VALIDATE_JSTF ) { error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf ); if ( error ) goto Exit; } if ( ot_flags & FT_VALIDATE_MATH ) { error = otv_load_table( face, TTAG_MATH, &math, &len_math ); if ( error ) goto Exit; } /* validate tables */ if ( base ) { ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_BASE_validate( base, &valid ); error = valid.error; if ( error ) goto Exit; } if ( gpos ) { ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_GPOS_validate( gpos, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; } if ( gsub ) { ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_GSUB_validate( gsub, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; } if ( gdef ) { ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; } if ( jstf ) { ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; } if ( math ) { ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_MATH_validate( math, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; } *ot_base = (FT_Bytes)base; *ot_gdef = (FT_Bytes)gdef; *ot_gpos = (FT_Bytes)gpos; *ot_gsub = (FT_Bytes)gsub; *ot_jstf = (FT_Bytes)jstf; Exit: if ( error ) { FT_Memory memory = FT_FACE_MEMORY( face ); FT_FREE( base ); FT_FREE( gdef ); FT_FREE( gpos ); FT_FREE( gsub ); FT_FREE( jstf ); } { FT_Memory memory = FT_FACE_MEMORY( face ); FT_FREE( math ); /* Can't return this as API is frozen */ } return error; }
static FT_Error otv_validate( FT_Face volatile face, FT_UInt ot_flags, FT_Bytes *ot_base, FT_Bytes *ot_gdef, FT_Bytes *ot_gpos, FT_Bytes *ot_gsub, FT_Bytes *ot_jstf ) { FT_Error error = OTV_Err_Ok; FT_Byte* volatile base; FT_Byte* volatile gdef; FT_Byte* volatile gpos; FT_Byte* volatile gsub; FT_Byte* volatile jstf; FT_Byte* volatile math; FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; FT_ULong len_math; FT_ValidatorRec volatile valid; base = gdef = gpos = gsub = jstf = math = NULL; len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0; /* load tables */ if ( ot_flags & FT_VALIDATE_BASE ) { error = otv_load_table( face, TTAG_BASE, &base, &len_base ); if ( error ) goto Exit; } if ( ot_flags & FT_VALIDATE_GDEF ) { error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef ); if ( error ) goto Exit; } if ( ot_flags & FT_VALIDATE_GPOS ) { error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos ); if ( error ) goto Exit; } if ( ot_flags & FT_VALIDATE_GSUB ) { error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub ); if ( error ) goto Exit; } if ( ot_flags & FT_VALIDATE_JSTF ) { error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf ); if ( error ) goto Exit; } if ( ot_flags & FT_VALIDATE_MATH ) { error = otv_load_table( face, TTAG_MATH, &math, &len_math ); if ( error ) goto Exit; } /* validate tables */ if ( base ) { ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_BASE_validate( base, &valid ); error = valid.error; if ( error ) goto Exit; } if ( gpos ) { ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_GPOS_validate( gpos, face->num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; } if ( gsub ) { ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_GSUB_validate( gsub, face->num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; } if ( gdef ) { ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_GDEF_validate( gdef, gsub, gpos, face->num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; } if ( jstf ) { ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_JSTF_validate( jstf, gsub, gpos, face->num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; } if ( math ) { ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) otv_MATH_validate( math, face->num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; } *ot_base = (FT_Bytes)base; *ot_gdef = (FT_Bytes)gdef; *ot_gpos = (FT_Bytes)gpos; *ot_gsub = (FT_Bytes)gsub; *ot_jstf = (FT_Bytes)jstf; Exit: if ( error ) { FT_Memory memory = FT_FACE_MEMORY( face ); FT_FREE( base ); FT_FREE( gdef ); FT_FREE( gpos ); FT_FREE( gsub ); FT_FREE( jstf ); } { FT_Memory memory = FT_FACE_MEMORY( face ); FT_FREE( math ); /* Can't return this as API is frozen */ } return error; }