2
* Copyright © 2006 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>
28
COMPIZ_PLUGIN_20081216 (imgpng, PngPluginVTable)
30
PngScreen::PngScreen (CompScreen *screen) :
31
PrivateHandler<PngScreen, CompScreen> (screen)
33
ScreenInterface::setHandler (screen, true);
35
screen->updateDefaultIcon ();
38
PngScreen::~PngScreen ()
40
screen->updateDefaultIcon ();
44
premultiplyData (png_structp png,
45
png_row_infop row_info,
50
for (i = 0; i < row_info->rowbytes; i += 4)
52
unsigned char *base = &data[i];
53
unsigned char blue = base[0];
54
unsigned char green = base[1];
55
unsigned char red = base[2];
56
unsigned char alpha = base[3];
59
red = (unsigned) red * (unsigned) alpha / 255;
60
green = (unsigned) green * (unsigned) alpha / 255;
61
blue = (unsigned) blue * (unsigned) alpha / 255;
63
p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
64
memcpy (base, &p, sizeof (int));
69
PngScreen::readPngData (png_struct *png,
74
png_uint_32 pngWidth, pngHeight;
75
int depth, colorType, interlace, i;
76
unsigned int pixelSize;
77
png_byte **rowPointers;
80
png_read_info (png, info);
82
png_get_IHDR (png, info,
83
&pngWidth, &pngHeight, &depth,
84
&colorType, &interlace, NULL, NULL);
86
size.setWidth (pngWidth);
87
size.setHeight (pngHeight);
89
/* convert palette/gray image to rgb */
90
if (colorType == PNG_COLOR_TYPE_PALETTE)
91
png_set_palette_to_rgb (png);
93
/* expand gray bit depth if needed */
94
if (colorType == PNG_COLOR_TYPE_GRAY && depth < 8)
95
png_set_gray_1_2_4_to_8 (png);
97
/* transform transparency to alpha */
98
if (png_get_valid(png, info, PNG_INFO_tRNS))
99
png_set_tRNS_to_alpha (png);
102
png_set_strip_16 (png);
105
png_set_packing (png);
107
/* convert grayscale to RGB */
108
if (colorType == PNG_COLOR_TYPE_GRAY ||
109
colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
110
png_set_gray_to_rgb (png);
112
if (interlace != PNG_INTERLACE_NONE)
113
png_set_interlace_handling (png);
116
png_set_filler (png, 0xff, PNG_FILLER_AFTER);
118
png_set_read_user_transform_fn (png, premultiplyData);
120
png_read_update_info (png, info);
123
d = (char *) malloc (pngWidth * pngHeight * pixelSize);
129
rowPointers = new png_byte *[pngHeight];
136
for (i = 0; i < pngHeight; i++)
137
rowPointers[i] = (png_byte *) (d + i * pngWidth * pixelSize);
139
png_read_image (png, rowPointers);
140
png_read_end (png, info);
142
delete [] rowPointers;
148
stdioReadFunc (png_structp png,
152
std::ifstream *file = (std::ifstream *) png_get_io_ptr (png);
154
file->read ((char *) data, size);
156
png_error (png, "Read Error");
160
PngScreen::readPng (std::ifstream &file,
164
unsigned char png_sig[PNG_SIG_SIZE];
169
file.read ((char *) png_sig, PNG_SIG_SIZE);
172
if (png_check_sig (png_sig, PNG_SIG_SIZE) == 0)
175
png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
179
info = png_create_info_struct (png);
182
png_destroy_read_struct (&png, NULL, NULL);
186
png_set_read_fn (png, &file, stdioReadFunc);
187
png_set_sig_bytes (png, PNG_SIG_SIZE);
189
status = readPngData (png, info, data, size);
191
png_destroy_read_struct (&png, &info, NULL);
197
stdioWriteFunc (png_structp png,
201
std::ofstream *file = (std::ofstream *) png_get_io_ptr (png);
203
file->write ((char *) data, size);
205
png_error (png, "Write Error");
209
PngScreen::writePng (unsigned char *buffer,
218
int i, height = size.height ();
220
rows = new png_byte *[height];
224
for (i = 0; i < height; i++)
225
rows[height - i - 1] = buffer + i * stride;
227
png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
234
info = png_create_info_struct (png);
237
png_destroy_write_struct (&png, NULL);
242
if (setjmp (png_jmpbuf (png)))
244
png_destroy_write_struct (&png, NULL);
249
png_set_write_fn (png, &file, stdioWriteFunc, NULL);
251
png_set_IHDR (png, info,
252
size.width (), size.height (), 8,
253
PNG_COLOR_TYPE_RGB_ALPHA,
255
PNG_COMPRESSION_TYPE_DEFAULT,
256
PNG_FILTER_TYPE_DEFAULT);
262
png_set_bKGD (png, info, &white);
264
png_write_info (png, info);
265
png_write_image (png, rows);
266
png_write_end (png, info);
268
png_destroy_write_struct (&png, &info);
275
PngScreen::fileNameWithExtension (CompString &path)
277
unsigned int len = path.length ();
279
if (len > 4 && path.substr (len - 4, 4) == ".png")
282
return path + ".png";
286
PngScreen::imageToFile (CompString &path,
294
CompString fileName = fileNameWithExtension (path);
298
file.open (fileName.c_str ());
301
status = writePng ((unsigned char *) data, file, size, stride);
309
status = screen->imageToFile (path, format, size, stride, data);
313
file.open (fileName.c_str ());
316
status = writePng ((unsigned char *) data, file, size, stride);
325
PngScreen::fileToImage (CompString &name,
332
CompString fileName = fileNameWithExtension (name);
334
file.open (fileName.c_str ());
337
status = readPng (file, size, data);
343
stride = size.width () * 4;
347
return screen->fileToImage (name, size, stride, data);
351
PngPluginVTable::init ()
353
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
357
getMetadata ()->addFromFile (name ());