freetype-devel
[Top][All Lists]
Advanced

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

Re: [ft-devel] FT_Bitmap_Convert and 1bpp bitmaps


From: Werner LEMBERG
Subject: Re: [ft-devel] FT_Bitmap_Convert and 1bpp bitmaps
Date: Tue, 16 Mar 2010 07:54:20 +0100 (CET)

> First of all "source->width >> 3" is 0 for widths < 8 and the whole
> loop is skipped. So we need to make the condition j >= 0.

This is definitely a bug.

> Next thing is "tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );" etc etc..
> The corresponding bit is masked and shifted.  But this way only the
> LSB is set.  As the original bitmap was monochromatic I believe we
> need to set all 8 bits to 1 (setting the whole byte to 0xff) in case
> "val & 0x80" equals to 1 or set them to 0 otherwise.

This is something which I would like to discuss.  The `normalization'
of bitmaps could be done on the application side too – we are getting
into undocumented behaviour.  Have a look at the patch below: I'm not
sure whether the multiplication by `0x55' and `0x11' for the 2pp->8pp
and 4pp->8pp cases is a good idea, given that in most situations you
have to apply gamma correction or similar operations anyway, and if
you do this with a table it's easier to have values 0-3 and 0-15 for
indexing instead of 0x00, 0x11, 0x22, etc.

Are there any other users of these functions on the list?  Opinions?


    Werner


======================================================================


--- ftbitmap.c.old      2009-07-31 18:45:18.000000000 +0200
+++ ftbitmap.c  2010-03-16 07:49:53.000000000 +0100
@@ -1,27 +1,27 @@
 /***************************************************************************/
 /*                                                                         */
 /*  ftbitmap.c                                                             */
 /*                                                                         */
 /*    FreeType utility functions for bitmaps (body).                       */
 /*                                                                         */
-/*  Copyright 2004, 2005, 2006, 2007, 2008, 2009 by                        */
+/*  Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010 by                  */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
 /*  modified, and distributed under the terms of the FreeType project      */
 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
 /*  this file you indicate that you have read the license and              */
 /*  understand and accept it fully.                                        */
 /*                                                                         */
 /***************************************************************************/
 
 
 #include <ft2build.h>
 #include FT_BITMAP_H
 #include FT_IMAGE_H
 #include FT_INTERNAL_OBJECTS_H
 
 
   static
   const FT_Bitmap  null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
@@ -430,68 +430,69 @@
 
     switch ( source->pixel_mode )
     {
     case FT_PIXEL_MODE_MONO:
       {
         FT_Byte*  s = source->buffer;
         FT_Byte*  t = target->buffer;
         FT_Int    i;
 
 
         target->num_grays = 2;
 
         for ( i = source->rows; i > 0; i-- )
         {
           FT_Byte*  ss = s;
           FT_Byte*  tt = t;
           FT_Int    j;
 
 
           /* get the full bytes */
-          for ( j = source->width >> 3; j > 0; j-- )
+          for ( j = source->width >> 3; j >= 0; j-- )
           {
             FT_Int  val = ss[0]; /* avoid a byte->int cast on each line */
 
 
-            tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
-            tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
-            tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
-            tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
-            tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
-            tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
-            tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
-            tt[7] = (FT_Byte)(   val & 0x01 );
+            tt[0] = ( val & 0x80 ) ? 0xFF : 0;
+            tt[1] = ( val & 0x40 ) ? 0xFF : 0;
+            tt[2] = ( val & 0x20 ) ? 0xFF : 0;
+            tt[3] = ( val & 0x10 ) ? 0xFF : 0;
+            tt[4] = ( val & 0x08 ) ? 0xFF : 0;
+            tt[5] = ( val & 0x04 ) ? 0xFF : 0;
+            tt[6] = ( val & 0x02 ) ? 0xFF : 0;
+            tt[7] = ( val & 0x01 ) ? 0xFF : 0;
 
             tt += 8;
             ss += 1;
           }
 
           /* get remaining pixels (if any) */
           j = source->width & 7;
           if ( j > 0 )
           {
             FT_Int  val = *ss;
 
 
             for ( ; j > 0; j-- )
             {
-              tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
+              tt[0] = ( val & 0x80 ) ? 0xFF : 0;
+
               val <<= 1;
               tt   += 1;
             }
           }
 
           s += source->pitch;
           t += target->pitch;
         }
       }
       break;
 
 
     case FT_PIXEL_MODE_GRAY:
     case FT_PIXEL_MODE_LCD:
     case FT_PIXEL_MODE_LCD_V:
       {
         FT_Int    width   = source->width;
         FT_Byte*  s       = source->buffer;
         FT_Byte*  t       = target->buffer;
         FT_Int    s_pitch = source->pitch;
@@ -512,106 +513,111 @@
       break;
 
 
     case FT_PIXEL_MODE_GRAY2:
       {
         FT_Byte*  s = source->buffer;
         FT_Byte*  t = target->buffer;
         FT_Int    i;
 
 
         target->num_grays = 4;
 
         for ( i = source->rows; i > 0; i-- )
         {
           FT_Byte*  ss = s;
           FT_Byte*  tt = t;
           FT_Int    j;
 
 
           /* get the full bytes */
-          for ( j = source->width >> 2; j > 0; j-- )
+          for ( j = source->width >> 2; j >= 0; j-- )
           {
             FT_Int  val = ss[0];
 
 
-            tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
-            tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
-            tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
-            tt[3] = (FT_Byte)( ( val & 0x03 ) );
+            tt[0] = (FT_Byte)( ( ( val & 0xC0 ) >> 6 ) * 0x55 );
+            tt[1] = (FT_Byte)( ( ( val & 0x30 ) >> 4 ) * 0x55 );
+            tt[2] = (FT_Byte)( ( ( val & 0x0C ) >> 2 ) * 0x55 );
+            tt[3] = (FT_Byte)( ( ( val & 0x03 )      ) * 0x55 );
 
             ss += 1;
             tt += 4;
           }
 
           j = source->width & 3;
           if ( j > 0 )
           {
             FT_Int  val = ss[0];
 
 
             for ( ; j > 0; j-- )
             {
-              tt[0]  = (FT_Byte)( ( val & 0xC0 ) >> 6 );
+              tt[0]  = (FT_Byte)( ( ( val & 0xC0 ) >> 6 ) * 0x55 );
               val  <<= 2;
               tt    += 1;
             }
           }
 
           s += source->pitch;
           t += target->pitch;
         }
       }
       break;
 
 
     case FT_PIXEL_MODE_GRAY4:
       {
         FT_Byte*  s = source->buffer;
         FT_Byte*  t = target->buffer;
         FT_Int    i;
 
 
         target->num_grays = 16;
 
         for ( i = source->rows; i > 0; i-- )
         {
           FT_Byte*  ss = s;
           FT_Byte*  tt = t;
           FT_Int    j;
 
 
           /* get the full bytes */
-          for ( j = source->width >> 1; j > 0; j-- )
+          for ( j = source->width >> 1; j >= 0; j-- )
           {
             FT_Int  val = ss[0];
 
 
-            tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
-            tt[1] = (FT_Byte)( ( val & 0x0F ) );
+            tt[0] = (FT_Byte)( ( ( val & 0xF0 ) >> 4 ) * 0x11 );
+            tt[1] = (FT_Byte)( ( ( val & 0x0F )      ) * 0x11 );
 
             ss += 1;
             tt += 2;
           }
 
           if ( source->width & 1 )
-            tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
+          {
+            FT_Int  val = ss[0];
+
+
+            tt[0] = (FT_Byte)( ( ( val & 0xF0 ) >> 4 ) * 0x11 );
+          }
 
           s += source->pitch;
           t += target->pitch;
         }
       }
       break;
 
 
     default:
       ;
     }
 
     return error;
   }
 
 
   /* documentation is in ftbitmap.h */
 
   FT_EXPORT_DEF( FT_Error )
   FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot  slot )

reply via email to

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