2
* Copyright © 2005 Novell, Inc.
4
* Permission to use, copy, modify, distribute, and sell this software
5
* and its documentation for any purpose is hereby granted without
6
* fee, provided that the above copyright notice appear in all copies
7
* and that both that copyright notice and this permission notice
8
* appear in supporting documentation, and that the name of
9
* Novell, Inc. not be used in advertising or publicity pertaining to
10
* distribution of the software without specific, written prior permission.
11
* Novell, Inc. makes no representations about the suitability of this
12
* software for any purpose. It is provided "as is" without express or
15
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17
* NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
* Author: David Reveman <davidr@novell.com>
34
#define HOME_IMAGEDIR ".compiz/images"
36
#define PNG_SIG_SIZE 8
39
premultiplyData (png_structp png,
40
png_row_infop row_info,
45
for (i = 0; i < row_info->rowbytes; i += 4)
47
unsigned char *base = &data[i];
48
unsigned char blue = base[0];
49
unsigned char green = base[1];
50
unsigned char red = base[2];
51
unsigned char alpha = base[3];
54
red = (unsigned) red * (unsigned) alpha / 255;
55
green = (unsigned) green * (unsigned) alpha / 255;
56
blue = (unsigned) blue * (unsigned) alpha / 255;
58
p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
59
memcpy (base, &p, sizeof (int));
64
readPngData (png_struct *png,
70
png_uint_32 png_width, png_height;
71
int depth, color_type, interlace, i;
72
unsigned int pixel_size;
73
png_byte **row_pointers;
75
png_read_info (png, info);
77
png_get_IHDR (png, info,
78
&png_width, &png_height, &depth,
79
&color_type, &interlace, NULL, NULL);
84
/* convert palette/gray image to rgb */
85
if (color_type == PNG_COLOR_TYPE_PALETTE)
86
png_set_palette_to_rgb (png);
88
/* expand gray bit depth if needed */
89
if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8)
90
png_set_gray_1_2_4_to_8 (png);
92
/* transform transparency to alpha */
93
if (png_get_valid(png, info, PNG_INFO_tRNS))
94
png_set_tRNS_to_alpha (png);
97
png_set_strip_16 (png);
100
png_set_packing (png);
102
/* convert grayscale to RGB */
103
if (color_type == PNG_COLOR_TYPE_GRAY ||
104
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
105
png_set_gray_to_rgb (png);
107
if (interlace != PNG_INTERLACE_NONE)
108
png_set_interlace_handling (png);
111
png_set_filler (png, 0xff, PNG_FILLER_AFTER);
113
png_set_read_user_transform_fn (png, premultiplyData);
115
png_read_update_info (png, info);
118
*data = (char *) malloc (png_width * png_height * pixel_size);
122
row_pointers = (png_byte **) malloc (png_height * sizeof (char *));
129
for (i = 0; i < png_height; i++)
130
row_pointers[i] = (png_byte *) (*data + i * png_width * pixel_size);
132
png_read_image (png, row_pointers);
133
png_read_end (png, info);
141
readPng (const char *filename,
144
unsigned int *height)
146
unsigned char png_sig[PNG_SIG_SIZE];
153
file = fopen (filename, "r");
156
char *home, *imagedir;
158
home = getenv ("HOME");
161
imagedir = malloc (strlen (home) +
162
strlen (HOME_IMAGEDIR) +
163
strlen (filename) + 3);
166
sprintf (imagedir, "%s/%s/%s", home, HOME_IMAGEDIR, filename);
167
file = fopen (imagedir, "r");
174
imagedir = malloc (strlen (IMAGEDIR) + strlen (filename) + 2);
177
sprintf (imagedir, "%s/%s", IMAGEDIR, filename);
178
file = fopen (imagedir, "r");
187
sig_bytes = fread (png_sig, 1, PNG_SIG_SIZE, file);
188
if (png_check_sig (png_sig, sig_bytes) == 0)
194
png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
198
info = png_create_info_struct (png);
201
png_destroy_read_struct (&png, NULL, NULL);
207
png_init_io (png, file);
208
png_set_sig_bytes (png, sig_bytes);
210
status = readPngData (png, info, data, width, height);
212
png_destroy_read_struct (&png, &info, NULL);
219
userReadData (png_structp png_ptr,
223
const unsigned char **buffer = (const unsigned char **)
224
png_get_io_ptr (png_ptr);
226
memcpy (data, *buffer, length);
231
readPngBuffer (const unsigned char *buffer,
234
unsigned int *height)
236
unsigned char png_sig[PNG_SIG_SIZE];
239
const unsigned char *b = buffer + PNG_SIG_SIZE;
242
memcpy (png_sig, buffer, PNG_SIG_SIZE);
243
if (png_check_sig (png_sig, PNG_SIG_SIZE) == 0)
246
png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
250
info = png_create_info_struct (png);
253
png_destroy_read_struct (&png, NULL, NULL);
257
png_set_read_fn (png, (void *) &b, userReadData);
258
png_set_sig_bytes (png, PNG_SIG_SIZE);
260
status = readPngData (png, info, data, width, height);
262
png_destroy_read_struct (&png, &info, NULL);