Esempio n. 1
0
//
// Expands RGB to ARGB allocating new buffer for it.
//
static gpointer
expand_rgb_to_argb (MoonPixbuf *pixbuf)
{
	guchar *pb_pixels = pixbuf->GetPixels ();
	guchar *p;
	int w = pixbuf->GetWidth ();
	int h = pixbuf->GetHeight ();
	int stride = w * 4;
	guchar *data = (guchar *) g_malloc (stride * h);
	guchar *out;

	for (int y = 0; y < h; y ++) {
		p = pb_pixels + y * pixbuf->GetRowStride ();
		out = data + y * (stride);
		for (int x = 0; x < w; x ++) {
			guchar r, g, b;

			get_pixel_bgr_p (p, b, g, r);
			set_pixel_bgra (out, 0, r, g, b, 255);

			p += 3;
			out += 4;
		}
	}

	return (gpointer) data;
}
Esempio n. 2
0
//
// Converts RGBA unmultiplied alpha to ARGB pre-multiplied alpha.
//
static gpointer
premultiply_rgba (MoonPixbuf *pixbuf)
{
	guchar *pb_pixels = pixbuf->GetPixels ();
	guchar *p;
	int w = pixbuf->GetWidth ();
	int h = pixbuf->GetHeight ();
	int stride = w * 4;
	guchar *data = (guchar *) g_malloc (stride * h);
	guchar *out;

	for (int y = 0; y < h; y ++) {
		p = pb_pixels + y * pixbuf->GetRowStride ();
		out = data + y * (stride);
		for (int x = 0; x < w; x ++) {
			guchar r, g, b, a;

			get_pixel_bgra (p, b, g, r, a);

			/* pre-multipled alpha */
			if (a == 0) {
				r = g = b = 0;
			}
			else if (a < 255) {
				r = pre_multiplied_table [r][a];
				g = pre_multiplied_table [g][a];
				b = pre_multiplied_table [b][a];
			}

			/* store it back, swapping red and blue */
			set_pixel_bgra (out, 0, r, g, b, a);

			p += 4;
			out += 4;
		}
	}

	return (gpointer) data;
}
Esempio n. 3
0
static GpStatus
gdip_load_png_image_from_file_or_stream (FILE *fp, GetBytesDelegate getBytesFunc, GpImage **image)
{
    png_structp	png_ptr = NULL;
    png_infop	info_ptr = NULL;
    png_infop	end_info_ptr = NULL;
    BYTE		*rawdata = NULL;
    GpImage		*result = NULL;
    GpStatus	status = InvalidParameter;
    int		bit_depth;
    int		channels;
    BYTE		color_type;

    png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

    if (!png_ptr) {
        goto error;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        /* png detected error occured */
        goto error;
    }

    info_ptr = png_create_info_struct (png_ptr);
    if (info_ptr == NULL) {
        goto error;
    }

    end_info_ptr = png_create_info_struct (png_ptr);
    if (end_info_ptr == NULL) {
        goto error;
    }

    if (fp != NULL) {
        png_init_io (png_ptr, fp);
    } else {
        png_set_read_fn (png_ptr, getBytesFunc, _gdip_png_stream_read_data);
    }

    png_read_png (png_ptr, info_ptr, 0, NULL);

    bit_depth = png_get_bit_depth (png_ptr, info_ptr);
    channels = png_get_channels (png_ptr, info_ptr);
    color_type = png_get_color_type (png_ptr, info_ptr);

    /* 2bpp is a special case (promoted to 32bpp ARGB by MS GDI+) */
    if ((bit_depth <= 8) && (bit_depth != 2) && (channels == 1) &&
            ((color_type == PNG_COLOR_TYPE_PALETTE)	|| (color_type == PNG_COLOR_TYPE_GRAY))) {
        int		width;
        int		height;
        int		source_stride;
        int		dest_stride;
        png_bytep	*row_pointers;
        BYTE		*rawptr;
        int		num_colours;
        int		palette_entries;
        ColorPalette	*palette;
        ImageFlags	colourspace_flag;
        int		i;
        int		j;

        width = png_get_image_width (png_ptr, info_ptr);
        height = png_get_image_height (png_ptr, info_ptr);

        source_stride = (width * bit_depth + 7) / 8;
        dest_stride = source_stride;
        gdip_align_stride (dest_stride);

        /* Copy image data. */
        row_pointers = png_get_rows (png_ptr, info_ptr);

        rawdata = GdipAlloc(dest_stride * height);
        for (i=0; i < height; i++) {
            memcpy (rawdata + i * dest_stride, row_pointers[i], source_stride);
        }

        /* Copy palette. */
        num_colours = 1 << bit_depth;

        if (png_get_color_type (png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY) {
            /* A gray-scale image; generate a palette fading from black to white. */
            colourspace_flag = ImageFlagsColorSpaceGRAY;
            palette = gdip_create_greyscale_palette (num_colours);
            palette->Flags = PaletteFlagsGrayScale;
        } else {
            /* Copy the palette data into the GDI+ structure. */
            colourspace_flag = ImageFlagsColorSpaceRGB;

            palette_entries = num_colours;
            if (palette_entries > info_ptr->num_palette) {
                palette_entries = info_ptr->num_palette;
            }

            palette = GdipAlloc (sizeof(ColorPalette) + (num_colours - 1) * sizeof(ARGB));
            palette->Flags = 0;
            palette->Count = num_colours;

            for (i=0; i < palette_entries; i++) {
                set_pixel_bgra (&palette->Entries[i], 0,
                                info_ptr->palette[i].blue,
                                info_ptr->palette[i].green,
                                info_ptr->palette[i].red,
                                0xFF); /* alpha */
            }
        }

        /* Make sure transparency is respected. */
        if (info_ptr->num_trans > 0) {
            palette->Flags |= PaletteFlagsHasAlpha;
            colourspace_flag |= ImageFlagsHasAlpha;

            if (info_ptr->num_trans > info_ptr->num_palette) {
                info_ptr->num_trans = info_ptr->num_palette;
            }

            for (i=0; i < info_ptr->num_trans; i++) {
                set_pixel_bgra(&palette->Entries[i], 0,
                               info_ptr->palette[i].blue,
                               info_ptr->palette[i].green,
                               info_ptr->palette[i].red,
#if PNG_LIBPNG_VER > 10399
                               info_ptr->trans_alpha [i]); /* alpha */
#else
                               info_ptr->trans[i]); /* alpha */
#endif
            }
        }