Author: jordi
Date: 2005-03-22 03:39:18 -0500 (Tue, 22 Mar 2005)
New Revision: 42069

Modified:
   trunk/libgdiplus/src/ChangeLog
   trunk/libgdiplus/src/bitmap.c
   trunk/libgdiplus/src/bmpcodec.c
   trunk/libgdiplus/src/gdip.h
   trunk/libgdiplus/src/imageattributes.c
Log:
2005-03-17  Jordi Mas i Hernandez  <[EMAIL PROTECTED]>

        * bmpcodec.c: 
          - Fixes 24 bits bitmap loading
          - Fixes leaks when exiting on error conditions
          - Sets the img->image.pixFormat propertly
          - Sets bmfh.bfOffBits when saving *before* start using it

        * imageattributes.c
          - Implements colour matrix processing and 
GdipSetImageAttributesColorMatrix

        * bitmap.c:
          - Fixes stride calculation (was causing many problems)
          - Moves set_pixel_bgra into bitmap.c and creates get_pixel_bgra



Modified: trunk/libgdiplus/src/ChangeLog
===================================================================
--- trunk/libgdiplus/src/ChangeLog      2005-03-22 07:44:20 UTC (rev 42068)
+++ trunk/libgdiplus/src/ChangeLog      2005-03-22 08:39:18 UTC (rev 42069)
@@ -1,3 +1,18 @@
+2005-03-17  Jordi Mas i Hernandez  <[EMAIL PROTECTED]>
+
+       * bmpcodec.c: 
+         - Fixes 24 bits bitmap loading
+         - Fixes leaks when exiting on error conditions
+         - Sets the img->image.pixFormat propertly
+         - Sets bmfh.bfOffBits when saving *before* start using it
+
+       * imageattributes.c
+         - Implements colour matrix processing and 
GdipSetImageAttributesColorMatrix
+
+       * bitmap.c:
+         - Fixes stride calculation (was causing many problems)
+         - Moves set_pixel_bgra into bitmap.c and creates get_pixel_bgra
+
 2005-03-18  Peter Bartok  <[EMAIL PROTECTED]>
 
        * graphics.c: Instead of throwing NotImpl exception, we display a 

Modified: trunk/libgdiplus/src/bitmap.c
===================================================================
--- trunk/libgdiplus/src/bitmap.c       2005-03-22 07:44:20 UTC (rev 42068)
+++ trunk/libgdiplus/src/bitmap.c       2005-03-22 08:39:18 UTC (rev 42069)
@@ -172,7 +172,7 @@
                int bpp  = gdip_get_pixel_format_components (format);
                bpp = bpp * gdip_get_pixel_format_depth (format);
                stride = (bpp * width) / 8;
-               stride += (stride + (sizeof(pixman_bits_t)-1));
+               stride = (stride + (sizeof(pixman_bits_t)-1));
                stride &= ~(sizeof(pixman_bits_t)-1);
        }
 
@@ -972,3 +972,37 @@
        return bitmap->image.surface;
 }
 
+#ifdef WORDS_BIGENDIAN
+void set_pixel_bgra (byte* pixel, int index, byte b, byte g, byte r, byte a)
+{
+       pixel[index+0] = a;
+       pixel[index+1] = r;
+       pixel[index+2] = g;
+       pixel[index+3] = b;
+} 
+
+void get_pixel_bgra (int pixel, byte* b, byte* g, byte* r, byte* a)
+{
+       *b = (color & 0xff000000) >> 24;
+       *g = (color & 0x00ff0000) >> 16;
+       *r = (color & 0x0000ff00) >> 8;
+       *a = (color & 0x000000ff);
+}
+
+#else
+void set_pixel_bgra (byte* pixel, int index, byte b, byte g, byte r, byte a)
+{
+       pixel[index+0] = b;
+       pixel[index+1] = g;
+       pixel[index+2] = r;
+       pixel[index+3] = a;
+}
+
+void get_pixel_bgra (int pixel, byte* b, byte* g, byte* r, byte* a)
+{
+       *a = ((pixel & 0xff000000) >> 24);
+       *r = ((pixel & 0x00ff0000) >> 16);
+       *g = ((pixel & 0x0000ff00) >> 8);
+       *b = (pixel & 0x000000ff);      
+}
+#endif

Modified: trunk/libgdiplus/src/bmpcodec.c
===================================================================
--- trunk/libgdiplus/src/bmpcodec.c     2005-03-22 07:44:20 UTC (rev 42068)
+++ trunk/libgdiplus/src/bmpcodec.c     2005-03-22 08:39:18 UTC (rev 42069)
@@ -179,38 +179,49 @@
        data_read = (byte*) GdipAlloc(size);
        memset (data_read, 0, size);
        size_read = gdip_read_bmp_data (pointer, data_read, size, useFile);
-       if (size_read < size)
+       if (size_read < size) {
+               GdipFree(data_read);
                return InvalidParameter;
+       }
        
        bmfh.bfType = ((data_read[1]<<8)|data_read[0]);
-       if (bmfh.bfType != BFT_BITMAP )
+       if (bmfh.bfType != BFT_BITMAP) {
+               GdipFree(data_read);
                return UnknownImageFormat;
+       }
 
        bmfh.bfSize = (data_read[5]<<24 | data_read[4]<<16 | data_read[3]<<8 | 
data_read[2]);
        bmfh.bfReserved1 = ((data_read[7]<<8)|data_read[6]);
        bmfh.bfReserved1 = ((data_read[9]<<8)|data_read[8]);
        bmfh.bfOffBits = (data_read[13]<<24 | data_read[12]<<16 | 
data_read[11]<<8 | data_read[10]);
-
        GdipFree(data_read);
 
        size = sizeof(DWORD);
        data_read = (byte*)GdipAlloc(size);
        size_read = gdip_read_bmp_data (pointer, data_read, size, useFile);
-       if (size_read < size)
+
+       if (size_read < size) {
+               GdipFree(data_read);
                return InvalidParameter;
+       }
+
        bmi.biSize = (data_read[3]<<24 | data_read[2]<<16 | data_read[1]<<8 | 
data_read[0]);
 
        if (bmi.biSize > BITMAPCOREHEADER_SIZE){   /* New Windows headers can 
be bigger */ 
                memset (data_read, 0, size);
                size_read = gdip_read_bmp_data (pointer, data_read, size, 
useFile);
-               if (size_read < size)
+               if (size_read < size) {
+                       GdipFree(data_read);
                        return InvalidParameter;
+               }
                bmi.biWidth = (data_read[3]<<24 | data_read[2]<<16 | 
data_read[1]<<8 | data_read[0]);
 
                memset (data_read, 0, size);
                size_read = gdip_read_bmp_data (pointer, data_read, size, 
useFile);
-               if (size_read < size)
+               if (size_read < size) {
+                       GdipFree(data_read);
                        return InvalidParameter;
+               }
                bmi.biHeight = (data_read[3]<<24 | data_read[2]<<16 | 
data_read[1]<<8 | data_read[0]);
        }
         else  {
@@ -218,31 +229,41 @@
                        /* Old OS/2 format. Width and Height fields are WORDs 
instead of DWORDS */
                         memset (data_read, 0, size);
                        size_read = gdip_read_bmp_data (pointer, data_read, 
size, useFile);
-                       if (size_read < size)
+                       if (size_read < size) {
+                               GdipFree(data_read);
                                return InvalidParameter;
+                       }
                        bmi.biWidth = (data_read[1]<<8 | data_read[0]);
                        bmi.biHeight = (data_read[3]<<8 | data_read[2]);
                         os2format = TRUE;
                 }
-                else
+                else {
+                       GdipFree(data_read);
                         return UnknownImageFormat;
+               }
         }
 
        memset (data_read, 0, size);
        size_read = gdip_read_bmp_data (pointer, data_read, size, useFile);
-       if (size_read < size)
+       if (size_read < size) {
+               GdipFree(data_read);
                return InvalidParameter;
+       }
        bmi.biPlanes = (data_read[1]<<8 | data_read[0]); 
        bmi.biBitCount = (data_read[3]<<8 | data_read[2]); 
 
        memset (data_read, 0, size);
        size_read = gdip_read_bmp_data (pointer, data_read, size, useFile);
-       if (size_read < size)
+       if (size_read < size) {
+               GdipFree(data_read);
                return InvalidParameter;
+       }
        bmi.biCompression = (data_read[3]<<24 | data_read[2]<<16 | 
data_read[1]<<8 | data_read[0]);
                
-        if (bmi.biCompression == BI_RLE4 || bmi.biCompression == BI_RLE8)
+        if (bmi.biCompression == BI_RLE4 || bmi.biCompression == BI_RLE8) {
+               GdipFree(data_read);
                 return NotImplemented; /* We do not support RLE for now*/
+       }
 
         if (bmi.biHeight < 0) { /* Negative height indicates that the bitmap 
is sideup*/
                 upsidedown = FALSE;
@@ -251,32 +272,43 @@
 
        memset (data_read, 0, size);
        size_read = gdip_read_bmp_data (pointer, data_read, size, useFile);
-       if (size_read < size)
+       if (size_read < size) {
+               GdipFree(data_read);
                return InvalidParameter;
+       }
        bmi.biSizeImage = (data_read[3]<<24 | data_read[2]<<16 | 
data_read[1]<<8 | data_read[0]);
                
        memset (data_read, 0, size);
        size_read = gdip_read_bmp_data (pointer, data_read, size, useFile);
-       if (size_read < size)
+       if (size_read < size) {
+               GdipFree(data_read);
                return InvalidParameter;
+       }
        bmi.biXPelsPerMeter = (data_read[3]<<24 | data_read[2]<<16 | 
data_read[1]<<8 | data_read[0]);
        
        memset (data_read, 0, size);
        size_read = gdip_read_bmp_data (pointer, data_read, size, useFile);
-       if (size_read < size)
+       if (size_read < size) {
+               GdipFree(data_read);
                return InvalidParameter;
+       }
        bmi.biYPelsPerMeter = (data_read[3]<<24 | data_read[2]<<16 | 
data_read[1]<<8 | data_read[0]);
                
        memset (data_read, 0, size);
        size_read = gdip_read_bmp_data (pointer, data_read, size, useFile);
-       if (size_read < size)
+       if (size_read < size) {
+               GdipFree(data_read);
                return InvalidParameter;
+       }
        bmi.biClrUsed = (data_read[3]<<24 | data_read[2]<<16 | data_read[1]<<8 
| data_read[0]);
                
        memset (data_read, 0, size);
        size_read = gdip_read_bmp_data (pointer, data_read, size, useFile);
-       if (size_read < size)
+       if (size_read < size) {
+               GdipFree(data_read);
                return InvalidParameter;
+       }
+
        bmi.biClrImportant = (data_read[3]<<24 | data_read[2]<<16 | 
data_read[1]<<8 | data_read[0]);
                
        colours =  (bmi.biClrUsed == 0 && bmi.biBitCount <= 8) ? (1 << 
bmi.biBitCount) : bmi.biClrUsed;
@@ -284,22 +316,22 @@
         format = gdip_get_pixelformat (bmi.biBitCount);
                                                
         img = gdip_bitmap_new ();
-        img->image.pixFormat = format;
         img->image.type = imageBitmap;
         img->image.width = bmi.biWidth;
         img->image.height = bmi.biHeight;
 
-        //img->data.PixelFormat = img->image.pixFormat;
-        img->data.PixelFormat = Format32bppArgb;
+        img->image.pixFormat = img->data.PixelFormat = Format32bppArgb;
         img->data.Width = img->image.width;
         img->data.Height = img->image.height;
 
        // We always assume 32 bit and translate into 32 bit from source format
         img->data.Stride = (32 * img->image.width) / 8;
         img->data.Stride = (img->data.Stride + 3) & ~3;
+
+       GdipFree(data_read);
      
         if (colours) {
-                img->image.palette = g_malloc (sizeof(ColorPalette) + 
sizeof(ARGB) * colours);
+                img->image.palette = GdipAlloc (sizeof(ColorPalette) + 
sizeof(ARGB) * colours);
                 img->image.palette->Flags = 0;
                 img->image.palette->Count = colours;
                        
@@ -311,6 +343,7 @@
                                memset(data_read, 0, size);
                                size_read = gdip_read_bmp_data (pointer, 
data_read, size, useFile);
                                if (size_read < size) {
+                                       GdipFree(data_read);
                                        return InvalidParameter;
                                }
                                img->image.palette->Entries[i] = 
@@ -365,6 +398,12 @@
                        break;
                }
 
+               case 24: {
+                       size = (((bmi.biBitCount * img->image.width) + 31) & 
~31) / 8;
+                       loop = img->image.width * 3;
+                       break;
+               }
+
                default: {
                        size = (((bmi.biBitCount * img->image.width) + 31) & 
~31) / 8;
                        loop = size; 
@@ -374,7 +413,6 @@
 
        data_read = (byte*) GdipAlloc(size);
 
-       //printf("Reading image data, upsidedown:%d, size: %d, stride:%d, 
loop:%d\n", upsidedown, size, img->data.Stride, loop);
        for (i = 0; i < img->data.Height; i++){ 
                if (upsidedown) {
                        line = img->data.Height - i - 1;
@@ -385,6 +423,7 @@
                size_read = gdip_read_bmp_data (pointer, data_read, size, 
useFile);
 
                if (size_read < size) {
+                       GdipFree(data_read);
                        return InvalidParameter;
                }
 
@@ -458,7 +497,6 @@
                                        index = (line * img->data.Stride);
                                        set_pixel_bgra(pixels, index+dest, 
data_read[src+0], data_read[src+1], data_read[src+2], 0xff);
                                        dest += 4;
-
                                        src += 3;
                                }
                                continue;
@@ -483,9 +521,12 @@
        }
 
        GdipFree(data_read);
-       g_free(img->image.palette);
-       img->image.palette = NULL;
 
+       if (img->image.palette) {
+               GdipFree(img->image.palette);
+               img->image.palette = NULL;
+       }
+
        img->data.Scan0 = pixels;
         img->data.Reserved = GBD_OWN_SCAN0;
         img->image.surface = cairo_surface_create_for_image ((char *)pixels,
@@ -502,7 +543,6 @@
         img->image.propItems = NULL;
 
         *image = (GpImage *) img;
-
         return Ok;
 }
 
@@ -548,13 +588,14 @@
 #ifdef WORDS_BIGENDIAN
        bmfh.bfReserved1 = bmfh.bfReserved2 = GUINT16_FROM_LE (0);
        bmfh.bfType = GUINT16_FROM_LE (BFT_BITMAP);
-       bmfh.bfSize = GUINT32_FROM_LE (bmfh.bfOffBits + bitmapLen);
-        bmfh.bfOffBits = GUINT32_FROM_LE (14 + 40 + colours * 4);
+       bmfh.bfOffBits = GUINT32_FROM_LE (14 + 40 + colours * 4);
+       bmfh.bfSize = GUINT32_FROM_LE (bmfh.bfOffBits + bitmapLen);        
 #else
         bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
         bmfh.bfType = BFT_BITMAP;
+        bmfh.bfOffBits = (14 + 40 + colours * 4);
         bmfh.bfSize = (bmfh.bfOffBits + bitmapLen);
-        bmfh.bfOffBits = (14 + 40 + colours * 4);
+
 #endif
         gdip_write_bmp_data (pointer, (byte *)&bmfh, sizeof (bmfh), useFile);
         
@@ -606,6 +647,7 @@
                GdipFree (row_pointer);
        }
 #else
+       
         for (i = bitmap->data.Height - 1; i >= 0; i--) {
                gdip_write_bmp_data (pointer, bitmap->data.Scan0 + i 
*bitmap->data.Stride, bitmap->data.Stride, useFile);
        }

Modified: trunk/libgdiplus/src/gdip.h
===================================================================
--- trunk/libgdiplus/src/gdip.h 2005-03-22 07:44:20 UTC (rev 42068)
+++ trunk/libgdiplus/src/gdip.h 2005-03-22 08:39:18 UTC (rev 42069)
@@ -43,22 +43,6 @@
 #define        gdip_cairo_ft_font_lock_face(font)      cairo_ft_font_face(font)
 #define gdip_cairo_ft_font_unlock_face(font)
 
-#ifdef WORDS_BIGENDIAN
-#define set_pixel_bgra(pixel,index,b,g,r,a) do {\
-                pixel[index+0] = a; \
-                pixel[index+1] = r; \
-                pixel[index+2] = g; \
-                pixel[index+3] = b; \
-        } while (0);
-#else
-#define set_pixel_bgra(pixel,index,b,g,r,a) do {\
-                pixel[index+0] = b; \
-                pixel[index+1] = g; \
-                pixel[index+2] = r; \
-                pixel[index+3] = a; \
-        } while (0);
-#endif
-
 #ifdef CAIRO_HAS_XLIB_SURFACE
 #ifdef USE_INCLUDED_CAIRO
 #include <cairo-xlib.h>
@@ -856,6 +840,8 @@
        ARGB key_colorhigh;
        BOOL key_enabled;
        BOOL no_op;
+       GpColorMatrix *colormatrix;
+       BOOL colormatrix_enabled;
 } GpImageAttribute;
 
 typedef struct {
@@ -1250,6 +1236,8 @@
 cairo_surface_t * gdip_bitmap_ensure_surface (GpBitmap *bitmap);
 
 const EncoderParameter *gdip_find_encoder_parameter (GDIPCONST 
EncoderParameters *eps, const GUID *guid);
+void set_pixel_bgra (byte* pixel, int index, byte b, byte g, byte r, byte a);
+void get_pixel_bgra (int pixel, byte* b, byte* g, byte* r, byte* a); 
 
 /* Stream handling bits */
 typedef int (*GetHeaderDelegate) (unsigned char *, int);

Modified: trunk/libgdiplus/src/imageattributes.c
===================================================================
--- trunk/libgdiplus/src/imageattributes.c      2005-03-22 07:44:20 UTC (rev 
42068)
+++ trunk/libgdiplus/src/imageattributes.c      2005-03-22 08:39:18 UTC (rev 
42069)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Ximian
+ * Copyright (c) 2004-2005 Ximian
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a 
copy of this software 
  * and associated documentation files (the "Software"), to deal in the 
Software without restriction, 
@@ -17,7 +17,7 @@
  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  * 
  * Author:
- *          Jordi Mas i Hernandez <[EMAIL PROTECTED]>, 2004
+ *          Jordi Mas i Hernandez <[EMAIL PROTECTED]>, 2004-2005
  *
  */
 
@@ -33,13 +33,22 @@
        attr->key_colorlow = 0;
        attr->key_colorhigh = 0;
        attr->key_enabled = FALSE;      
+       attr->colormatrix = NULL;
+       attr->colormatrix_enabled = FALSE;
 }
 
 void
 gdip_dispose_image_attribute (GpImageAttribute* attr)
 {
-       if (attr->colormap)
+       if (attr->colormap) {
                free (attr->colormap);
+               attr->colormap = NULL;
+       }
+
+       if (attr->colormatrix) {
+               free (attr->colormatrix);
+               attr->colormatrix = NULL;
+       }
 }
 
 
@@ -65,6 +74,7 @@
 void
 gdip_process_bitmap_attributes (GpBitmap *bitmap, void **dest, 
GpImageAttributes* attr, bool *allocated)
 { 
+
        GpImageAttribute *imgattr;
        void *scan0;
        GpBitmap bmpdest;
@@ -85,7 +95,8 @@
        if (!imgattr->colormap_elem || !imgattr->gamma_correction || 
!imgattr->key_enabled) 
                imgattr = gdip_get_image_attribute (attr, 
ColorAdjustTypeDefault);
                
-       if (imgattr->colormap_elem || imgattr->gamma_correction || 
imgattr->key_enabled) {
+       if (imgattr->colormap_elem || imgattr->gamma_correction || 
imgattr->key_enabled
+               || (imgattr->colormatrix_enabled && imgattr->colormatrix)) {
                scan0 = malloc (bitmap->data.Stride * bitmap->data.Height);
                memcpy (scan0, bitmap->data.Scan0, bitmap->data.Stride * 
bitmap->data.Height);
                *dest = scan0;
@@ -167,6 +178,41 @@
                }
        
        }
+
+       /* Apply Color Matrix */
+       if (imgattr->colormatrix_enabled && imgattr->colormatrix) {             
+               for (y = 0; y <bitmap->data.Height; y++) {      
+                       for (x = 0; x <bitmap->data.Width; x++) {
+
+                               byte r,g,b,a;
+                               int r_new,g_new,b_new,a_new;
+                               
+                               GdipBitmapGetPixel (&bmpdest, x, y, &color);
+                               get_pixel_bgra (color, &b, &g, &r, &a);
+
+                               r_new = (r * imgattr->colormatrix->m[0][0] + g 
* imgattr->colormatrix->m[1][0] + b * imgattr->colormatrix->m[2][0] +
+                                       a * imgattr->colormatrix->m[3][0] + 
(255 * imgattr->colormatrix->m[4][0]));
+
+                               g_new = (r * imgattr->colormatrix->m[0][1] + g 
* imgattr->colormatrix->m[1][1] + b * imgattr->colormatrix->m[2][1] +
+                                       a * imgattr->colormatrix->m[3][1] + 
(255 * imgattr->colormatrix->m[4][1]));
+
+                               b_new = (r * imgattr->colormatrix->m[0][2] + g 
* imgattr->colormatrix->m[1][2] + b * imgattr->colormatrix->m[2][2] +
+                                       a * imgattr->colormatrix->m[3][2] + 
(255 * imgattr->colormatrix->m[4][2]));
+
+                               a_new = (r * imgattr->colormatrix->m[0][3] + g 
* imgattr->colormatrix->m[1][3] + b * imgattr->colormatrix->m[2][3] +
+                                       a * imgattr->colormatrix->m[3][3] + 
(255 * imgattr->colormatrix->m[4][3]));
+                       
+                               if (r_new > 0xff) r_new = 0xff;
+                               if (g_new > 0xff) g_new = 0xff;
+                               if (b_new > 0xff) b_new = 0xff;
+                               if (a_new > 0xff) a_new = 0xff;
+
+                               set_pixel_bgra ((byte *)&color, 0, (byte) 
b_new, (byte) g_new, (byte) r_new, (byte) a_new);
+                               GdipBitmapSetPixel (&bmpdest, x, y, color);
+                       }       
+               }
+       
+       }
 }
 
 
@@ -202,7 +248,7 @@
 
        result = (GpImageAttributes *) GdipAlloc (sizeof (GpImageAttributes));
 
-       memcpy (result, imageattr, sizeof (GpStringFormat));
+       memcpy (result, imageattr, sizeof (GpImageAttributes));
 
        *cloneImageattr = result;
        return Ok; 
@@ -359,12 +405,24 @@
 GdipSetImageAttributesColorMatrix (GpImageAttributes *imageattr, 
ColorAdjustType type, BOOL enableFlag,  GpColorMatrix* colorMatrix,
        GpColorMatrix* grayMatrix, GpColorMatrixFlags flags)
 {
-       static int      called = 0;
+       GpImageAttribute *imgattr;
+       
+       if (!imageattr)
+               return InvalidParameter;
+               
+       imgattr = gdip_get_image_attribute (imageattr, type);
+       
+       if (!imgattr)
+               return InvalidParameter;
 
-       if (!called) {
-               printf("NOT IMPLEMENTED YET: GdipSetImageAttributesColorMatrix 
(GpImageAttributes *imageattr, ColorAdjustType type, BOOL enableFlag,  
GpColorMatrix* colorMatrix, GpColorMatrix* grayMatrix, GpColorMatrixFlags 
flags)\n");
+       if (colorMatrix) {
+               if (imgattr->colormatrix == NULL)
+                       imgattr->colormatrix =  malloc (sizeof (GpColorMatrix));
+
+               memcpy (imgattr->colormatrix, colorMatrix, sizeof 
(GpColorMatrix));
        }
-       //return NotImplemented;
+
+       imgattr->colormatrix_enabled = enableFlag;      
        return Ok;
 }
        

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to