Commit e99b9a99d7ff1025d6b8694c5be81c7871811a8e

David Turner 2005-02-10T16:11:29

* src/base/ftbitmap.c (FT_Bitmap_Convert): small improvements to the conversion function (mainly stupid optimization, because I like these... shame on me) * src/base/Jamfile: adding ftbitmap.c to the list of compiled files

diff --git a/ChangeLog b/ChangeLog
index 68d13d2..ac8f8c0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,12 @@
 	dynamic array when loading a glyph from a PFR font. This fixes
 	bug #11921
 
+	* src/base/ftbitmap.c (FT_Bitmap_Convert): small improvements to the
+	conversion function (mainly stupid optimization, because I like
+	these... shame on me)
+
+	* src/base/Jamfile: adding ftbitmap.c to the list of compiled files
+
 2005-02-10  Werner Lemberg  <wl@gnu.org>
 
 	* builds/unix/freetype-config.in: Add new flag `--ftversion' to
diff --git a/src/base/Jamfile b/src/base/Jamfile
index f46e9b4..b00c7c9 100644
--- a/src/base/Jamfile
+++ b/src/base/Jamfile
@@ -10,7 +10,7 @@ SubDir  FT2_TOP $(FT2_SRC_DIR) base ;
   if $(FT2_MULTI)
   {
     _sources = ftutil ftdbgmem ftstream ftcalc fttrigon ftgloadr ftoutln
-               ftobjs ftnames ftrfork ;
+               ftobjs ftnames  ftrfork  ;
   }
   else
   {
@@ -24,7 +24,7 @@ SubDir  FT2_TOP $(FT2_SRC_DIR) base ;
 #
 Library  $(FT2_LIB) : ftsystem.c   ftinit.c    ftglyph.c  ftmm.c     ftbdf.c
                       ftbbox.c     ftdebug.c   ftxf86.c   fttype1.c  ftpfr.c
-                      ftstroke.c   ftwinfnt.c  ftotval.c ;
+                      ftstroke.c   ftwinfnt.c  ftotval.c  ftbitmap.c ;
 
 # Add Macintosh-specific file to the library when necessary.
 #
diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
index ea62aa2..1ad4556 100644
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -46,8 +46,6 @@
   {
     FT_Error   error = FT_Err_Ok;
     FT_Memory  memory;
-    FT_Int     i, j, old_size;
-    FT_Byte    *s, *ss, *t, *tt;
 
 
     if ( !library )
@@ -61,174 +59,201 @@
     case FT_PIXEL_MODE_GRAY:
     case FT_PIXEL_MODE_GRAY2:
     case FT_PIXEL_MODE_GRAY4:
-      old_size = target->rows * target->pitch;
+      {
+        FT_Int   pad;
+        FT_Long  old_size;
+
+        old_size = target->rows * target->pitch;
+        if ( old_size < 0 )
+          old_size = -old_size;
+
+        target->pixel_mode = FT_PIXEL_MODE_GRAY;
+        target->rows       = source->rows;
+        target->width      = source->width;
 
-      target->pixel_mode = FT_PIXEL_MODE_GRAY;
-      target->rows       = source->rows;
-      target->width      = source->width;
-      target->pitch      = ( source->width + alignment - 1 )
-                             / alignment * alignment;
+        pad = 0;
+        if ( alignment > 0 )
+        {
+          pad = source->width % alignment;
+          if ( pad != 0 )
+            pad = alignment - pad;
+        }
 
-      if ( target->rows * target->pitch > old_size )
-        if ( FT_QREALLOC( target->buffer,
+        target->pitch = source->width + pad;
+
+        if ( target->rows * target->pitch > old_size &&
+             FT_QREALLOC( target->buffer,
                           old_size, target->rows * target->pitch ) )
           return error;
-
+      }
       break;
 
     default:
       error = FT_Err_Invalid_Argument;
     }
 
-    s = source->buffer;
-    t = target->buffer;
-
     switch ( source->pixel_mode )
     {
     case FT_PIXEL_MODE_MONO:
-      target->num_grays = 2;
-
-      for ( i = 0; i < source->rows; i++ )
       {
-        ss = s;
-        tt = t;
+        FT_Byte*  s = source->buffer;
+        FT_Byte*  t = target->buffer;
+        FT_Int    i;
 
-        /* get the full bytes */
-        for ( j = 0; j < ( source->width >> 3 ); j++ )
-        {
-          *(tt++) = (FT_Byte)( ( *ss & 0x80 ) >> 7 );
-          *(tt++) = (FT_Byte)( ( *ss & 0x40 ) >> 6 );
-          *(tt++) = (FT_Byte)( ( *ss & 0x20 ) >> 5 );
-          *(tt++) = (FT_Byte)( ( *ss & 0x10 ) >> 4 );
-          *(tt++) = (FT_Byte)( ( *ss & 0x08 ) >> 3 );
-          *(tt++) = (FT_Byte)( ( *ss & 0x04 ) >> 2 );
-          *(tt++) = (FT_Byte)( ( *ss & 0x02 ) >> 1 );
-          *(tt++) = (FT_Byte)(   *ss & 0x01 );
-
-          ss++;
-        }
+        target->num_grays = 2;
 
-        /* get remaining pixels (if any) */
-        switch ( source->width & 7 )
+        for ( i = source->rows; i > 0; i-- )
         {
-        case 7:
-          *(tt++) = (FT_Byte)( ( *ss & 0x80 ) >> 7 );
-          /* fall through */
-        case 6:
-          *(tt++) = (FT_Byte)( ( *ss & 0x40 ) >> 6 );
-          /* fall through */
-        case 5:
-          *(tt++) = (FT_Byte)( ( *ss & 0x20 ) >> 5 );
-          /* fall through */
-        case 4:
-          *(tt++) = (FT_Byte)( ( *ss & 0x10 ) >> 4 );
-          /* fall through */
-        case 3:
-          *(tt++) = (FT_Byte)( ( *ss & 0x08 ) >> 3 );
-          /* fall through */
-        case 2:
-          *(tt++) = (FT_Byte)( ( *ss & 0x04 ) >> 2 );
-          /* fall through */
-        case 1:
-          *(tt++) = (FT_Byte)( ( *ss & 0x02 ) >> 1 );
-          /* fall through */
-        case 0:
-          break;
+          FT_Byte*  ss = s;
+          FT_Byte*  tt = t;
+          FT_Int    j;
+
+          /* get the full bytes */
+          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 += 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);
+              val <<= 1;
+              tt   += 1;
+            }
+          }
+
+          s += source->pitch;
+          t += target->pitch;
         }
-
-        s += source->pitch;
-        t += target->pitch;
       }
       break;
 
-    case FT_PIXEL_MODE_GRAY:
-      target->num_grays = 256;
 
-      for ( i = 0; i < source->rows; i++ )
+    case FT_PIXEL_MODE_GRAY:
       {
-        ss = s;
-        tt = t;
+        FT_Int    width   = source->width;
+        FT_Byte*  s       = source->buffer;
+        FT_Byte*  t       = target->buffer;
+        FT_Int    s_pitch = source->pitch;
+        FT_Int    t_pitch = target->pitch;
+        FT_Int    i;
 
-        for ( j = 0; j < source->width; j++ )
-          *(tt++) = *(ss++);
+        target->num_grays = 256;
+
+        for ( i = source->rows; i > 0; i-- )
+        {
+          FT_ARRAY_COPY( t, s, width );
 
-        s += source->pitch;
-        t += target->pitch;
+          s += s_pitch;
+          t += t_pitch;
+        }
       }
       break;
 
-    case FT_PIXEL_MODE_GRAY2:
-      target->num_grays = 4;
 
-      for ( i = 0; i < source->rows; i++ )
+    case FT_PIXEL_MODE_GRAY2:
       {
-        ss = s;
-        tt = t;
+        FT_Byte*  s = source->buffer;
+        FT_Byte*  t = target->buffer;
+        FT_Int    i;
 
-        /* get the full bytes */
-        for ( j = 0; j < ( source->width >> 2 ); j++ )
-        {
-          *(tt++) = (FT_Byte)( ( *ss & 0xC0 ) >> 6 );
-          *(tt++) = (FT_Byte)( ( *ss & 0x30 ) >> 4 );
-          *(tt++) = (FT_Byte)( ( *ss & 0x0C ) >> 2 );
-          *(tt++) = (FT_Byte)(   *ss & 0x03 );
+        target->num_grays = 4;
 
-          ss++;
-        }
-
-        /* get remaining pixels (if any) */
-        switch ( source->width & 3 )
+        for ( i = source->rows; i > 0; i-- )
         {
-        case 3:
-          *(tt++) = (FT_Byte)( ( *ss & 0xC0 ) >> 6 );
-          /* fall through */
-        case 2:
-          *(tt++) = (FT_Byte)( ( *ss & 0x30 ) >> 4 );
-          /* fall through */
-        case 1:
-          *(tt++) = (FT_Byte)( ( *ss & 0x0C ) >> 2 );
-          /* fall through */
-        case 0:
-          break;
+          FT_Byte*  ss = s;
+          FT_Byte*  tt = t;
+          FT_Int    j;
+
+          /* get the full bytes */
+          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) );
+
+            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 );
+              val  <<= 2;
+              tt    += 1;
+            }
+          }
+
+          s += source->pitch;
+          t += target->pitch;
         }
-
-        s += source->pitch;
-        t += target->pitch;
       }
       break;
 
-    case FT_PIXEL_MODE_GRAY4:
-      target->num_grays = 16;
 
-      for ( i = 0; i < source->rows; i++ )
+    case FT_PIXEL_MODE_GRAY4:
       {
-        ss = s;
-        tt = t;
+        FT_Byte*  s = source->buffer;
+        FT_Byte*  t = target->buffer;
+        FT_Int    i;
 
-        /* get the full bytes */
-        for ( j = 0; j < ( source->width >> 1 ); j++ )
+        target->num_grays = 16;
+
+        for ( i = source->rows; i > 0; i-- )
         {
-          *(tt++) = (FT_Byte)( ( *ss & 0xF0 ) >> 4 );
-          *(tt++) = (FT_Byte)(   *ss & 0x0F );
+          FT_Byte*  ss = s;
+          FT_Byte*  tt = t;
+          FT_Int    j;
 
-          ss++;
-        }
+          /* get the full bytes */
+          for ( j = source->width >> 1; j > 0; j-- )
+          {
+            FT_Int  val = ss[0];
 
-        /* get remaining pixels (if any) */
-        switch ( source->width & 1 )
-        {
-        case 1:
-          *(tt++) = (FT_Byte)( ( *ss & 0xF0 ) >> 4 );
-          /* fall through */
-        case 0:
-          break;
-        }
+            tt[0] = (FT_Byte)( (val & 0xF0) >> 4 );
+            tt[1] = (FT_Byte)( (val & 0x0F) );
 
-        s += source->pitch;
-        t += target->pitch;
+            ss += 1;
+            tt += 2;
+          }
+
+          if ( source->width & 1 )
+            tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
+
+          s += source->pitch;
+          t += target->pitch;
+        }
       }
       break;
 
+    default:
+      ;
     }
 
     return error;