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