patch by Pieter Grimmerink: use ext3 largefile option only for disks > 4G
[enigma2.git] / lib / gdi / gpixmap.cpp
index aaffbaa71c8743c16b18d9dcb2a5bbbe8650ea80..e2960ad71f2257dc70f4ae0af0cf637969e728ce 100644 (file)
@@ -106,7 +106,7 @@ gSurface::gSurface(eSize size, int _bpp, int accel)
        clut.data = 0;
 
        if (!data)
-               data = malloc(y * stride);
+               data = new unsigned char [y * stride];
        
        type = 1;
 }
@@ -118,9 +118,9 @@ gSurface::~gSurface()
                if (data_phys)
                        gAccel::getInstance()->accelFree(data_phys);
                else
-                       free(data);
+                       delete [] (unsigned char*)data;
 
-               delete[] clut.data;
+               delete [] clut.data;
        }
 }
 
@@ -175,6 +175,86 @@ void gPixmap::fill(const gRegion &region, const gColor &color)
        }
 }
 
+void gPixmap::fill(const gRegion &region, const gRGB &color)
+{
+       unsigned int i;
+       for (i=0; i<region.rects.size(); ++i)
+       {
+               const eRect &area = region.rects[i];
+               if ((area.height()<=0) || (area.width()<=0))
+                       continue;
+
+               if (surface->bpp == 32)
+               {
+                       __u32 col;
+
+                       col = color.argb();
+                       col^=0xFF000000;
+
+                       if (surface->data_phys && gAccel::getInstance())
+                               if (!gAccel::getInstance()->fill(surface,  area, col))
+                                       continue;
+
+                       for (int y=area.top(); y<area.bottom(); y++)
+                       {
+                               __u32 *dst=(__u32*)(((__u8*)surface->data)+y*surface->stride+area.left()*surface->bypp);
+                               int x=area.width();
+                               while (x--)
+                                       *dst++=col;
+                       }
+               }       else
+                       eWarning("couldn't rgbfill %d bpp", surface->bpp);
+       }
+}
+
+static void blit_8i_to_32(__u32 *dst, __u8 *src, __u32 *pal, int width)
+{
+       while (width--)
+               *dst++=pal[*src++];
+}
+
+static void blit_8i_to_32_at(__u32 *dst, __u8 *src, __u32 *pal, int width)
+{
+       while (width--)
+       {
+               if (!(pal[*src]&0x80000000))
+               {
+                       src++;
+                       dst++;
+               } else
+                       *dst++=pal[*src++];
+       }
+}
+
+               /* WARNING, this function is not endian safe! */
+static void blit_8i_to_32_ab(__u32 *dst, __u8 *src, __u32 *pal, int width)
+{
+       while (width--)
+       {
+#define BLEND(x, y, a) (y + (((x-y) * a)>>8))
+               __u32 srccol = pal[*src++];
+               __u32 dstcol = *dst;
+               unsigned char sb = srccol & 0xFF;
+               unsigned char sg = (srccol >> 8) & 0xFF;
+               unsigned char sr = (srccol >> 16) & 0xFF;
+               unsigned char sa = (srccol >> 24) & 0xFF;
+
+               unsigned char db = dstcol & 0xFF;
+               unsigned char dg = (dstcol >> 8) & 0xFF;
+               unsigned char dr = (dstcol >> 16) & 0xFF;
+               unsigned char da = (dstcol >> 24) & 0xFF;
+
+               da = BLEND(0xFF, da, sa) & 0xFF;
+               dr = BLEND(sr, dr, sa) & 0xFF;
+               dg = BLEND(sg, dg, sa) & 0xFF;
+               db = BLEND(sb, db, sa) & 0xFF;
+
+#undef BLEND
+               *dst++ = db | (dg << 8) | (dr << 16) | (da << 24);
+       }
+}
+
+
 void gPixmap::blit(const gPixmap &src, ePoint pos, const gRegion &clip, int flag)
 {
        for (unsigned int i=0; i<clip.rects.size(); ++i)
@@ -188,17 +268,16 @@ void gPixmap::blit(const gPixmap &src, ePoint pos, const gRegion &clip, int flag
 
                eRect srcarea=area;
                srcarea.moveBy(-pos.x(), -pos.y());
-               
+
                if ((surface->data_phys && src.surface->data_phys) && (gAccel::getInstance()))
                        if (!gAccel::getInstance()->blit(surface, src.surface, area.topLeft(), srcarea, flag))
                                continue;
-               flag &= ~ blitAlphaBlend;
-               
+
                if ((surface->bpp == 8) && (src.surface->bpp==8))
                {
                        __u8 *srcptr=(__u8*)src.surface->data;
                        __u8 *dstptr=(__u8*)surface->data;
-       
+
                        srcptr+=srcarea.left()*src.surface->bypp+srcarea.top()*src.surface->stride;
                        dstptr+=area.left()*surface->bypp+area.top()*surface->stride;
                        for (int y=0; y<area.height(); y++)
@@ -228,7 +307,7 @@ void gPixmap::blit(const gPixmap &src, ePoint pos, const gRegion &clip, int flag
                {
                        __u32 *srcptr=(__u32*)src.surface->data;
                        __u32 *dstptr=(__u32*)surface->data;
-       
+
                        srcptr+=srcarea.left()+srcarea.top()*src.surface->stride/4;
                        dstptr+=area.left()+area.top()*surface->stride/4;
                        for (int y=0; y<area.height(); y++)
@@ -251,7 +330,7 @@ void gPixmap::blit(const gPixmap &src, ePoint pos, const gRegion &clip, int flag
                                } else if (flag & blitAlphaBlend)
                                {
                                        // uh oh. this is only until hardware accel is working.
-                                       
+
                                        int width=area.width();
                                                        // ARGB color space!
                                        unsigned char *src=(unsigned char*)srcptr;
@@ -269,12 +348,13 @@ void gPixmap::blit(const gPixmap &src, ePoint pos, const gRegion &clip, int flag
                                                unsigned char dr = dst[2];
                                                unsigned char dg = dst[1];
                                                unsigned char db = dst[0];
-                                               
+
                                                dst[3] = BLEND(0xFF, da, sa);
                                                dst[2] = BLEND(sr, dr, sa);
                                                dst[1] = BLEND(sg, dg, sa);
                                                dst[0] = BLEND(sb, db, sa);
-                                               
+#undef BLEND
+
                                                src += 4; dst += 4;
                                        }
                                } else
@@ -296,40 +376,25 @@ void gPixmap::blit(const gPixmap &src, ePoint pos, const gRegion &clip, int flag
                                        pal[i]=0x010101*i;
                                pal[i]^=0xFF000000;
                        }
-       
+
                        srcptr+=srcarea.left()*src.surface->bypp+srcarea.top()*src.surface->stride;
                        dstptr+=area.left()*surface->bypp+area.top()*surface->stride;
                        for (int y=0; y<area.height(); y++)
                        {
+                               int width=area.width();
+                               unsigned char *psrc=(unsigned char*)srcptr;
+                               __u32 *dst=(__u32*)dstptr;
                                if (flag & blitAlphaTest)
-                               {
-                     // no real alphatest yet
-                                       int width=area.width();
-                                       unsigned char *src=(unsigned char*)srcptr;
-                                       __u32 *dst=(__u32*)dstptr;
-                                               // use duff's device here!
-                                       while (width--)
-                                       {
-                                               if (*src==0x01)
-                                               {
-                                                       src++;
-                                                       dst++;
-                                               } else
-                                                       *dst++=pal[*src++];
-                                       }
-                               } else
-                               {
-                                       int width=area.width();
-                                       unsigned char *src=(unsigned char*)srcptr;
-                                       __u32 *dst=(__u32*)dstptr;
-                                       while (width--)
-                                               *dst++=pal[*src++];
-                               }
+                                       blit_8i_to_32_at(dst, psrc, pal, width);
+                               else if (flag & blitAlphaBlend)
+                                       blit_8i_to_32_ab(dst, psrc, pal, width);
+                               else
+                                       blit_8i_to_32(dst, psrc, pal, width);
                                srcptr+=src.surface->stride;
                                dstptr+=surface->stride;
                        }
                } else
-                       eFatal("cannot blit %dbpp from %dbpp", surface->bpp, src.surface->bpp);
+                       eWarning("cannot blit %dbpp from %dbpp", surface->bpp, src.surface->bpp);
        }
 }
 
@@ -379,7 +444,7 @@ void gPixmap::line(const gRegion &clip, ePoint start, ePoint dst, gColor color)
        if (clip.rects.empty())
                return;
                
-       __u32 col;
+       __u32 col = 0;
        if (surface->bpp == 8)
        {
                srf8 = (__u8*)surface->data;
@@ -438,7 +503,7 @@ void gPixmap::line(const gRegion &clip, ePoint start, ePoint dst, gColor color)
                        do
                        {
                                ++a;
-                               if (a == clip.rects.size())
+                               if ((unsigned int)a == clip.rects.size())
                                        a = 0;
                                if (a == lasthit)
                                {
@@ -506,13 +571,17 @@ DEFINE_REF(gPixmap);
 
 gPixmap::~gPixmap()
 {
+       if (must_delete_surface)
+               delete surface;
 }
 
-gPixmap::gPixmap(gSurface *surface): surface(surface)
+gPixmap::gPixmap(gSurface *surface)
+       :surface(surface), must_delete_surface(false)
 {
 }
 
 gPixmap::gPixmap(eSize size, int bpp, int accel)
+       :must_delete_surface(true)
 {
        surface = new gSurface(size, bpp, accel);
 }