freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ft-devel] Fw: [ft] Memory Stomp problem in FT_Bitmap_Embolden


From: Werner LEMBERG
Subject: [ft-devel] Fw: [ft] Memory Stomp problem in FT_Bitmap_Embolden
Date: Fri, 12 Jan 2007 06:28:07 +0100 (CET)

David, please have a look.  This looks like a valid argument.


    Werner
--- Begin Message --- Subject: Re: [ft] Memory Stomp problem in FT_Bitmap_Embolden Date: Mon, 08 Jan 2007 14:26:47 -0500 User-agent: Thunderbird 1.5.0.9 (X11/20061206)
Hi -

I just checked out the latest version from CVS and the problem is still there.

The code assumes that the new embolden'ed bitmap will have a equal or larger pitch
than the existing bitmap.

Since you are making a bold version of the bitmap this would seem to always be the case However if the original bitmap has excess padding on the right then the new bitmap can turn out to be narrower than the original bitmap. Bitmaps produced by the monochrome renderer are always padded to the next 16 bit boundary so they many times have extra padding on the right. The pitch of the new bitmap ignores the pitch of the original bitmap, the new pitch is computed only from the width in pixels of the original bitmap. So the new bitmap gets minimum padding and ends up being smaller than the original bitmap with extra
padding.

The loop which copies the scan lines always copies the number of bytes in the original bitmaps pitch.

If the new bitmap is narrower than the original bitmap when the last scan line of the bitmap is copied from the old to the new it writes 1 or more bytes past the end of allocated memory.

The memcpy at line 174 in ftbitmap.c moves pitch bytes into a bitmap which can be pitch-1 bytes wide.

My test code is attached along with my output. The output shows that the bold bitmap has a pitch of 3 while the original bitmap has a pitch of 4. I don't have any problem running this code on Linux, different malloc,
but in our embedded OS the bitmap free hits an assert.

Thanks, Ted Packard


FTPATH := /home/tpackard/freetype/cvs
#FTPATH := /home/tpackard/freetype/freetype-2.2.1

embold: embold.c $(FTPATH)/objs/.libs/libfreetype.a
        gcc -o embold -I $(FTPATH)/include embold.c 
$(FTPATH)/objs/.libs/libfreetype.a


#include <stdio.h>
#include <ft2build.h>  
#include FT_FREETYPE_H
#include FT_STROKER_H

#define TRUE 1
#define FALSE 0

#define ERROR_CHECK( s ) {      \
        if ( error ) {  \
                printf("Function %s returned %d\n", s, error ); \
                exit( 1 ); \
        }       \
        else {  \
                printf("%s success\n", s );     \
        }       \
}

struct Args {
        char* fontFileName;
        int pointSize;
        int charCode;
};

static struct Args rtn;

static void error_exit() {
        printf( "What, try embold charcode \n\t\t\t[ -f FileName ]\n\t\t\t[ -p 
PointSize ]\n" );
        exit( 1 );
}

// process command line arugments
struct Args *processArgs( int argc, char **argv ) {

        rtn.fontFileName = "/usr/share/fonts/bitstream-vera/Vera.ttf";
        rtn.pointSize = 40 << 6;
        rtn.charCode = 65;

        float ftemp;;
        int ccode;

        if ( argc < 2 )
                error_exit();
        
        argc--; // skip pgm name
        argv++;

        sscanf( *argv, "%x", &ccode );
        rtn.charCode = ccode;

        argc--; // skip charcode
        argv++;

        while( argc ) {
                
                char *cmd = *argv;
                argv++;
                char *data = *argv;
                argv++;
        
                argc -= 2;

                if ( cmd[0] != '-' )
                        error_exit();

                int c = cmd[1];
                switch( c ) {
        
                        case 'f':
                                rtn.fontFileName = data;
                                break;
                                
                        case 'p':
                                sscanf( data, "%f", &ftemp );
                                rtn.pointSize = (int)( ( ftemp * 64.0 ) + 0.5 );
                                break;
                }
        }
        return &rtn;
}

// Debug routine to dump an alpha mask bitmap to the screen as ascii hex values
void dumpMonoBitmap( FT_Bitmap *bm, int left, int top ) {

        int x, y, bit;
        int rows   = bm->rows;
        int width  = bm->width;
        int pitch  = bm->pitch;
        unsigned char *buffer = bm->buffer;
        unsigned char *p = buffer;
        unsigned char pixel;

        printf("rows = %d, width = %d, pitch = %d, bufer = %p\n", rows, width, 
pitch, buffer );
        printf("left = %d top = %d\n", left, top );

        for ( y = 0; y < rows; y++ ) {
                for ( x = 0; x < pitch; x++ ) {
                        for ( bit = 0; bit < 8; bit++ ) {
                                int b = *p;
                                int v = b << bit;
                                if ( v & 0x80 )
                                        printf(" *" );
                                else
                                        printf("  ");   
                        }
                        p++;
                }
                printf("\n");
        }
}

main( int argc, char **argv ) {

        FT_Library library;
        FT_Face face;
        FT_Error error;
        FT_Glyph glyph;

        int glyph_index;
        struct Args *args = processArgs( argc, argv );

        error = FT_Init_FreeType( &library );
        ERROR_CHECK( "FT_Init_FreeType" );

        error = FT_New_Face( library, args->fontFileName, 0, &face );
        ERROR_CHECK( "FT_New_Face" );

        error = FT_Set_Char_Size( face, 0, args->pointSize, 72, 72 );
        ERROR_CHECK( "FT_Set_Char_Size" );

        glyph_index = FT_Get_Char_Index( face, args->charCode );
        error = glyph_index == 0;
        ERROR_CHECK( "FT_Get_Char_Index" );

        // load scale and hint the glyph's outline
        error = FT_Load_Glyph( face, glyph_index, FT_LOAD_MONOCHROME );
        ERROR_CHECK( "FT_Load_Glyph" );

        error = FT_Render_Glyph( face->glyph,  FT_RENDER_MODE_MONO );
        ERROR_CHECK( "FT_Render_Glyph" );

        dumpMonoBitmap( &(face->glyph->bitmap), 0, 0 );

        int strength = 2 << 6;
        error = FT_Bitmap_Embolden( library, &(face->glyph->bitmap), strength, 
strength );
        ERROR_CHECK( "FT_Bitmap_Embolden" );

        dumpMonoBitmap( &(face->glyph->bitmap), 0, 0 );

        error = FT_Done_Face( face );
        ERROR_CHECK( "FT_Done_Face" );

        error = FT_Done_FreeType( library );
        ERROR_CHECK( "FT_Done_FreeType" );
}

FT_Init_FreeType success
FT_New_Face success
FT_Set_Char_Size success
FT_Get_Char_Index success
FT_Load_Glyph success
FT_Render_Glyph success
rows = 24, width = 20, pitch = 4, bufer = 0x8e2d5e8
left = 0 top = 0
                                                                
             * * * * * * * * *                                  
         * * * * * * * * * * * * *                              
       * * * * * * * * * * * * * * *                            
     * * * * *               * * * *                            
     * * * *                   * * * *                          
   * * * *                     * * * *                          
   * * *                         * * * *                        
 * * * *                         * * * *                        
 * * * *                         * * * *                        
 * * * * * * * * * * * * * * * * * * * *                        
 * * * * * * * * * * * * * * * * * * * *                        
 * * * * * * * * * * * * * * * * * * * *                        
 * * * *                                                        
 * * * *                                                        
 * * * *                                                        
   * * *                                                        
   * * * *                                                      
   * * * * *                                                    
     * * * * *                     * *                          
       * * * * * * * * * * * * * * * *                          
         * * * * * * * * * * * * * * *                          
             * * * * * * * * * * *                              
                                                                
FT_Bitmap_Embolden success
rows = 26, width = 22, pitch = 3, bufer = 0x8e2d650
left = 0 top = 0
                                                
             * * * * * * * * * * *              
         * * * * * * * * * * * * * * *          
       * * * * * * * * * * * * * * * * *        
     * * * * * * * * * * * * * * * * * *        
     * * * * * * * * * * * * * * * * * * *      
   * * * * * * * *           * * * * * * *      
   * * * * * * *               * * * * * * *    
 * * * * * * *                 * * * * * * *    
 * * * * * *                     * * * * * *    
 * * * * * * * * * * * * * * * * * * * * * *    
 * * * * * * * * * * * * * * * * * * * * * *    
 * * * * * * * * * * * * * * * * * * * * * *    
 * * * * * * * * * * * * * * * * * * * * * *    
 * * * * * * * * * * * * * * * * * * * * * *    
 * * * * * *                                    
 * * * * * *                                    
 * * * * * * *                                  
   * * * * * * *                                
   * * * * * * * *                 * * * *      
   * * * * * * * * * * * * * * * * * * * *      
     * * * * * * * * * * * * * * * * * * *      
       * * * * * * * * * * * * * * * * * *      
         * * * * * * * * * * * * * * * * *      
             * * * * * * * * * * * * *          
                                                
FT_Done_Face success
FT_Done_FreeType success

--- End Message ---

reply via email to

[Prev in Thread] Current Thread [Next in Thread]