Hi,

The BMP provider has a couple of bugs. The first is a faulty for condition for 1bit BMPs. The second is an incorrect palette lookup for 1 and 4bit BMPs. Both of them are fixed by the attached patch, which is unfortunately generated against DirectFB 1.0.

Sorin
Index: interfaces/IDirectFBImageProvider/idirectfbimageprovider_bmp.c
===================================================================
RCS file: /bigbig/dungeon/dcchd_project/directfb/install/dfb-smp86xx/interfaces/IDirectFBImageProvider/Attic/idirectfbimageprovider_bmp.c,v
retrieving revision 1.3
diff -u -r1.3 idirectfbimageprovider_bmp.c
--- interfaces/IDirectFBImageProvider/idirectfbimageprovider_bmp.c	2 Dec 2008 15:49:44 -0000	1.3
+++ interfaces/IDirectFBImageProvider/idirectfbimageprovider_bmp.c	3 Feb 2010 11:51:09 -0000
@@ -63,9 +63,9 @@
 
 typedef struct {
      int                    ref;
-     
+
      IDirectFBDataBuffer   *buffer;
-     
+
      int                    width;
      int                    height;
      int                    depth;
@@ -73,11 +73,11 @@
      BMPImageCompression    compression;
      unsigned int           img_offset;
      unsigned int           num_colors;
-     
+
      DFBColor              *palette;
-     
+
      CoreSurface           *image;
-     
+
      DIRenderCallback       render_callback;
      void                  *render_callback_ctx;
 } IDirectFBImageProvider_BMP_data;
@@ -96,7 +96,7 @@
           ret = buffer->WaitForData( buffer, len );
           if (ret == DFB_OK)
                ret = buffer->GetData( buffer, len, ptr, &read );
-          
+
           if (ret)
                return ret;
 
@@ -114,24 +114,24 @@
      __u8      buf[54];
      __u32     tmp;
      __u32     bihsize;
-     
+
      memset( buf, 0, sizeof(buf) );
-     
+
      ret = fetch_data( data->buffer, buf, sizeof(buf) );
      if (ret)
           return ret;
-      
-     /* 2 bytes: Magic */    
+
+     /* 2 bytes: Magic */
      if (buf[0] != 'B' && buf[1] != 'M') {
           D_ERROR( "IDirectFBImageProvider_BMP: "
                    "Invalid magic (%c%c)!\n", buf[0], buf[1] );
           return DFB_UNSUPPORTED;
      }
-          
+
      /* 4 bytes: FileSize */
-     
+
      /* 4 bytes: Reserved */
-     
+
      /* 4 bytes: DataOffset */
      data->img_offset = buf[10] | (buf[11]<<8) | (buf[12]<<16) | (buf[13]<<24);
      if (data->img_offset < 54) {
@@ -139,7 +139,7 @@
                    "Invalid offset %08x!\n", data->img_offset );
           return DFB_UNSUPPORTED;
      }
-          
+
      /* 4 bytes: HeaderSize */
      bihsize = buf[14] | (buf[15]<<8) | (buf[16]<<16) | (buf[17]<<24);
      if (bihsize < 40) {
@@ -147,7 +147,7 @@
                    "Invalid image header size %d!\n", bihsize );
           return DFB_UNSUPPORTED;
      }
-          
+
      /* 4 bytes: Width */
      data->width = buf[18] | (buf[19]<<8) | (buf[20]<<16) | (buf[21]<<24);
      if (data->width < 1 || data->width > 0xffff) {
@@ -155,7 +155,7 @@
                    "Invalid width %d!\n", data->width );
           return DFB_UNSUPPORTED;
      }
-          
+
      /* 4 bytes: Height */
      data->height = buf[22] | (buf[23]<<8) | (buf[24]<<16) | (buf[25]<<24);
      if (data->height < 1 || data->height > 0xffff) {
@@ -163,7 +163,7 @@
                    "Invalid height %d!\n", data->height );
           return DFB_UNSUPPORTED;
      }
-          
+
      /* 2 bytes: Planes */
      tmp = buf[26] | (buf[27]<<8);
      if (tmp != 1) {
@@ -171,7 +171,7 @@
                    "Unsupported number of planes %d!\n", tmp );
           return DFB_UNSUPPORTED;
      }
-          
+
      /* 2 bytes: Depth */
      data->depth = buf[28] | (buf[29]<<8);
      switch (data->depth) {
@@ -187,7 +187,7 @@
                         "Unsupported depth %d!\n", data->depth );
                return DFB_UNSUPPORTED;
      }
-     
+
      /* 4 bytes: Compression */
      data->compression = buf[30] | (buf[31]<<8) | (buf[32]<<16) | (buf[33]<<24);
      switch (data->compression) {
@@ -201,56 +201,70 @@
                         "Unsupported compression %d!\n", data->compression );
                return DFB_UNSUPPORTED;
      }
-     
+
      /* 4 bytes: CompressedSize */
-     
+
      /* 4 bytes: HorizontalResolution */
-     
+
      /* 4 bytes: VerticalResolution */
-     
+
      /* 4 bytes: UsedColors */
      data->num_colors = buf[46] | (buf[47]<<8) | (buf[48]<<16) | (buf[49]<<24);
      if (!data->num_colors)
           data->num_colors = 1 << data->depth;
-          
+
      /* 4 bytes: ImportantColors */
-     
+
      /* Skip remaining bytes */
      if (bihsize > 40) {
           bihsize -= 40;
           while (bihsize--) {
-               __u8 b; 
+               __u8 b;
                ret = fetch_data( data->buffer, &b, 1 );
                if (ret)
                     return ret;
           }
      }
-     
+
      /* Palette */
      if (data->indexed) {
           void *src;
-          int   i;
-          
-          data->palette = src = D_MALLOC( data->num_colors*4 );
+          int   i, j;
+
+          data->palette = src = D_MALLOC( 256*4 );
           if (!data->palette)
                return D_OOM();
-              
+
           ret = fetch_data( data->buffer, src, data->num_colors*4 );
           if (ret)
                return ret;
-                             
+
           for (i = 0; i < data->num_colors; i++) {
                DFBColor c;
-               
+
                c.a = 0xff;
                c.r = ((__u8*)src)[i*4+2];
                c.g = ((__u8*)src)[i*4+1];
                c.b = ((__u8*)src)[i*4+0];
-               
-               data->palette[i] = c;
+
+               /* For faster lookup, fill all 256 entries with duplicate data
+                  for every bit position */
+               switch (data->num_colors) {
+                    case 2:
+                         if (i == 0)
+                              data->palette[0] = c;
+                         else
+                              for (j = 1; j < 256; j++)
+                                   data->palette[j] = c;
+                         break;
+                    case 4:
+                         data->palette[i] = c;
+                         data->palette[i << 4] = c;
+                         break;
+               }
           }
      }
-     
+
      return DFB_OK;
 }
 
@@ -262,16 +276,16 @@
      __u8       buf[pitch];
      __u32     *dst;
      int        i;
-     
+
      ret = fetch_data( data->buffer, buf, pitch );
      if (ret)
           return ret;
-          
+
      dst = image + row * data->width;
-     
+
      switch (data->depth) {
           case 1:
-               for (i = 0; data->width; i++) {
+               for (i = 0; i < data->width; i++) {
                     unsigned idx = buf[i>>3] & (0x80 >> (i&7));
                     DFBColor c   = data->palette[idx];
                     dst[i] = c.b | (c.g << 8) | (c.r << 16) | (c.a << 24);
@@ -279,7 +293,7 @@
                break;
           case 4:
                for (i = 0; i < data->width; i++) {
-                    unsigned idx = buf[i>>1] & (0xf0 >> (i&1));
+                    unsigned idx = buf[i>>1] & (0xf0 >> ((i&1) << 2));
                     DFBColor c   = data->palette[idx];
                     dst[i] = c.b | (c.g << 8) | (c.r << 16) | (c.a << 24);
                }
@@ -294,7 +308,7 @@
                for (i = 0; i < data->width; i++) {
                     __u32 r, g, b;
                     __u16 c;
-                    
+
                     c = buf[i*2+0] | (buf[i*2+1]<<8);
                     r = (c >> 10) & 0x1f;
                     g = (c >>  5) & 0x1f;
@@ -302,13 +316,13 @@
                     r = (r << 3) | (r >> 2);
                     g = (g << 3) | (g >> 2);
                     b = (b << 3) | (b >> 2);
-                    
+
                     dst[i] = b | (g<<8) | (r<<16) | 0xff000000;
                }
                break;
           case 24:
                for (i = 0; i < data->width; i++) {
-                    dst[i] = (buf[i*3+0]    ) | 
+                    dst[i] = (buf[i*3+0]    ) |
                              (buf[i*3+1]<< 8) |
                              (buf[i*3+2]<<16) |
                              0xff000000;
@@ -316,19 +330,19 @@
                break;
           case 32:
                for (i = 0; i < data->width; i++) {
-                    dst[i] = (buf[i*4+2]    ) | 
+                    dst[i] = (buf[i*4+2]    ) |
                              (buf[i*4+1]<< 8) |
                              (buf[i*4+0]<<16) |
                              (buf[i*4+3]<<24);
                }
-               break; 
+               break;
           default:
                break;
      }
-     
+
      return DFB_OK;
-}    
-     
+}
+
 /*****************************************************************************/
 
 static void
@@ -338,10 +352,10 @@
 
      if (data->buffer)
           data->buffer->Release( data->buffer );
-     
+
      if (data->image)
           dfb_surface_unref(data->image);
-          
+
      if (data->palette)
           D_FREE( data->palette );
 
@@ -380,18 +394,18 @@
      DFBRectangle            src_rect;
      DFBRegion               clip;
      DFBResult               ret = DFB_OK;
-     
+
      DIRECT_INTERFACE_GET_DATA( IDirectFBImageProvider_BMP )
-     
+
      if (!destination)
           return DFB_INVARG;
-          
+
      dst_data = destination->priv;
      if (!dst_data || !dst_data->surface)
           return DFB_DESTROYED;
-          
+
      dst_surface = dst_data->surface;
-     
+
      if (dest_rect) {
           if (dest_rect->w < 1 || dest_rect->h < 1)
                return DFB_INVARG;
@@ -402,7 +416,7 @@
      else {
           rect = dst_data->area.wanted;
      }
-     
+
      dfb_region_from_rectangle( &clip, &dst_data->area.current );
      if (!dfb_rectangle_intersect_by_region( &rect, &clip ))
           return DFB_OK;
@@ -418,16 +432,16 @@
           palette->Release( palette );
      }
 
-     if (!data->image) 
+     if (!data->image)
      {
           int    y;
 
           __u32 *image_data;
           int    image_pitch;
 
-          ret = dfb_surface_create(dst_data->core, data->width, data->height, DSPF_RGB32, 
+          ret = dfb_surface_create(dst_data->core, data->width, data->height, DSPF_RGB32,
                                    CSP_VIDEOONLY, DSCAPS_VIDEOONLY, NULL, &data->image);
-          if (ret) 
+          if (ret)
                return D_OOM();
 
           ret = dfb_surface_soft_lock(dst_data->core, data->image, DSLF_WRITE, (void**)&image_data, &image_pitch, true);
@@ -436,15 +450,15 @@
                data->image = NULL;
                return D_OOM();
           }
-          
+
           data->buffer->SeekTo( data->buffer, data->img_offset );
-          
+
           for (y = data->height-1; y >= 0; y--) {
                ret = bmp_decode_rgb_row( data, image_data, y );
                if (ret)
                     break;
           }
-          
+
           dfb_surface_unlock(data->image, true);
 
           data->buffer->Release( data->buffer );
@@ -459,8 +473,8 @@
      dfb_state_set_blitting_flags( &dst_data->state, DSBLIT_NOFX );
      dfb_gfxcard_stretchblit( &src_rect, &rect, &dst_data->state );
      dfb_state_set_source( &dst_data->state, NULL );
-     
-     if (data->render_callback) 
+
+     if (data->render_callback)
           data->render_callback( &src_rect, data->render_callback_ctx );
 
      return ret;
_______________________________________________
directfb-dev mailing list
directfb-dev@directfb.org
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev

Reply via email to