[Top][All Lists]
[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 )